SQL Cheat Sheet
Concept
A compact quick reference. Standard syntax is shown; dialect variants are noted in comments.
Why It Matters
Useful for revision before interviews and as a desk reference while working.
Syntax
GROUP BY and HAVING
SELECT [DISTINCT] col1, col2 AS alias, expr
FROM table t
[JOIN other o ON o.key = t.key]
[WHERE condition]
[GROUP BY col1]
[HAVING aggregate_condition]
[ORDER BY col1 [ASC|DESC] [NULLS FIRST|LAST]]
[LIMIT n OFFSET m]; -- SQL Server: TOP (n) / OFFSET m ROWS FETCH NEXT n ROWS ONLY
-- Standard/Oracle: FETCH FIRST n ROWS ONLY
-- Logical order: FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT= <> != < > <= >=
AND OR NOT
BETWEEN a AND b -- inclusive
IN (v1, v2) NOT IN (...) -- NOT IN breaks with NULLs
LIKE 'A%' LIKE '_b%' -- % any chars, _ one char
IS NULL IS NOT NULL
EXISTS (subquery) NOT EXISTS (subquery)
x IS DISTINCT FROM y -- null-safe (MySQL: NOT (x <=> y))INSERT INTO t (c1, c2) VALUES (v1, v2);
INSERT INTO t (c1, c2) VALUES (v1, v2), (v3, v4);
INSERT INTO t (c1, c2) SELECT a, b FROM s WHERE ...;
INSERT INTO t (c1) VALUES (v1) RETURNING id; -- PostgreSQL/SQLite; SQL Server: OUTPUT INSERTED.id
INSERT INTO t (k, v) VALUES (1, 'x')
ON CONFLICT (k) DO UPDATE SET v = EXCLUDED.v; -- PostgreSQL/SQLite upsert
-- MySQL: ON DUPLICATE KEY UPDATE v = VALUES(v); SQL Server/Oracle: MERGEUPDATE t SET c1 = v1, c2 = c2 + 1 WHERE condition;
UPDATE t SET c = s.c FROM s WHERE s.id = t.id; -- PostgreSQL
UPDATE t JOIN s ON s.id = t.id SET t.c = s.c; -- MySQL
UPDATE t SET c = s.c FROM t JOIN s ON s.id = t.id; -- SQL ServerDELETE FROM t WHERE condition;
DELETE FROM t WHERE id IN (SELECT id FROM ...);
TRUNCATE TABLE t; -- all rows, fast, DDLCREATE TABLE orders (
order_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, -- MySQL: AUTO_INCREMENT; SQL Server: IDENTITY(1,1)
customer_id BIGINT NOT NULL,
order_date DATE NOT NULL DEFAULT CURRENT_DATE,
status VARCHAR(20) NOT NULL DEFAULT 'PENDING',
total DECIMAL(12,2) NOT NULL CHECK (total >= 0),
CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id)
REFERENCES customers (customer_id) ON DELETE RESTRICT,
CONSTRAINT chk_orders_status CHECK (status IN ('PENDING', 'SHIPPED', 'DELIVERED', 'CANCELLED'))
);ALTER TABLE t ADD COLUMN c VARCHAR(50); -- SQL Server/Oracle: ADD c ...
ALTER TABLE t DROP COLUMN c;
ALTER TABLE t RENAME COLUMN a TO b; -- SQL Server: sp_rename
ALTER TABLE t ALTER COLUMN c TYPE VARCHAR(100); -- PostgreSQL
ALTER TABLE t MODIFY c VARCHAR(100) NOT NULL; -- MySQL
ALTER TABLE t ALTER COLUMN c VARCHAR(100) NOT NULL; -- SQL Server
ALTER TABLE t ADD CONSTRAINT uq_t_c UNIQUE (c);
ALTER TABLE t DROP CONSTRAINT uq_t_c;
ALTER TABLE t RENAME TO t2;DROP TABLE t;
DROP TABLE IF EXISTS t;
DROP TABLE t CASCADE; -- PostgreSQL (Oracle: CASCADE CONSTRAINTS)PRIMARY KEY (c) -- unique + not null, one per table
FOREIGN KEY (c) REFERENCES p (pk) [ON DELETE CASCADE | SET NULL | RESTRICT]
UNIQUE (c1, c2)
NOT NULL
CHECK (condition) -- accepts NULL (UNKNOWN)
DEFAULT valueFROM a INNER JOIN b ON b.k = a.k -- matches only
FROM a LEFT JOIN b ON b.k = a.k -- all a (filters on b go in ON)
FROM a RIGHT JOIN b ON b.k = a.k -- all b
FROM a FULL JOIN b ON b.k = a.k -- all a and b (not MySQL)
FROM a CROSS JOIN b -- every combination
FROM emp e JOIN emp m ON m.id = e.mgr_id -- self join
FROM a LEFT JOIN b ON b.k = a.k WHERE b.k IS NULL -- anti-join: a without bExample
Quick "which tool?" guide:
How many per group?
GROUP BY + COUNT Rows with no match LEFT JOIN... IS NULL / NOT EXISTS Top N per group ROW_NUMBER / DENSE_RANK in CTE Compare with previous row
SUM() OVER (ORDER BY... ROWS UNBOUNDED PRECEDING) Rows to columns SUM(CASE...) / PIVOT Columns to rows UNION ALL / UNPIVOT / LATERAL VALUES ROW_NUMBER()... WHERE rn > 1
Expected Result
You can reconstruct any common query from this sheet within a few minutes.
Common Mistakes
Using the cheat sheet without checking your DBMS's dialect notes.
Best Practices
Print it, annotate it with your own dialect's syntax, and review it before interviews.
Practice Questions
Without looking, write the frame clause for a 7-row moving average.
Write the anti-join pattern two ways.