SQL Cheat Sheet
SQL cheat sheet online. Joins, data types, window functions, dates, and NULL handling for PostgreSQL, MySQL, and SQLite. Free searchable SQL reference.
SELECT
Core read query
SELECT col FROM t WHERE cond;Drop duplicate values
SELECT DISTINCT col FROM t;AS is optional in most engines
SELECT u.name AS user_name FROM users u;Postgres, MySQL, SQLite
SELECT * FROM t ORDER BY id LIMIT 10 OFFSET 20;T-SQL paging
SELECT * FROM t ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;JOINs
Matches only
FROM a INNER JOIN b ON a.id = b.a_idKeep all of a
FROM a LEFT JOIN b ON a.id = b.a_idKeep all of b
FROM a RIGHT JOIN b ON a.id = b.a_idKeep leftovers on both sides
FROM a FULL OUTER JOIN b ON a.id = b.a_idCartesian product
FROM a CROSS JOIN bRows in a with no b
FROM a LEFT JOIN b ON a.id = b.a_id WHERE b.id IS NULLSemi-join, one row per a
WHERE EXISTS (SELECT 1 FROM b WHERE b.a_id = a.id)NULL
Never use = NULL
WHERE col IS NULLFirst non-null. All engines
COALESCE(a, b, c)NULL if a equals b
NULLIF(a, b)MySQL / SQLite two-arg
IFNULL(a, b)SQL Server two-arg
ISNULL(a, b)Data types
Prefer TIMESTAMPTZ
INTEGER, BIGINT, NUMERIC, TEXT, BOOLEAN, TIMESTAMPTZ, JSONB, UUIDBOOLEAN is TINYINT
INT, BIGINT, DECIMAL, VARCHAR(n), TINYINT(1), DATETIME, JSONTypes are affinities
INTEGER, REAL, TEXT, BLOB, NUMERICNVARCHAR for unicode
INT, BIGINT, DECIMAL, NVARCHAR(n), BIT, DATETIME2, UNIQUEIDENTIFIERAggregates
COUNT(*) counts null rows
COUNT(*) / COUNT(col) / COUNT(DISTINCT col)Non-aggregated cols must be grouped
SELECT u.id, COUNT(*) FROM t GROUP BY u.idFilter groups, not rows
GROUP BY u.id HAVING COUNT(*) > 1Postgres / SQLite 3.30+
COUNT(*) FILTER (WHERE active)Window functions
1..n per partition
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC)Ties skip the next rank
RANK() OVER (ORDER BY score DESC)Previous / next row
LAG(col, 1) OVER (ORDER BY ts)Frame defaults to RANGE UNBOUNDED PRECEDING
SUM(amount) OVER (PARTITION BY user_id ORDER BY ts)Dates
Also week, month, year
DATE_TRUNC('day', ts)MySQL date helpers
DATE(ts) / DATE_FORMAT(ts, '%Y-%m-%d')SQLite date as string
strftime('%Y-%m-%d', ts)Postgres. MySQL: DATE_ADD(ts, INTERVAL 7 DAY)
ts + INTERVAL '7 days'NOW is Postgres/MySQL, GETDATE is T-SQL
CURRENT_TIMESTAMP / NOW() / GETDATE()Strings
MySQL || is OR unless PIPES_AS_CONCAT
col || 'x' -- Postgres, SQLite
CONCAT(col, 'x') -- MySQL, SQL Server% any, _ one char
WHERE name LIKE 'A%' ESCAPE '\'Postgres only
WHERE name ILIKE '%smith%'All engines
TRIM(BOTH FROM col) / LTRIM / RTRIMLEN is SQL Server
CHAR_LENGTH(col) / LEN(col)INSERT / UPDATE / DELETE
List columns explicitly
INSERT INTO t (a, b) VALUES (1, 'x');Copy rows
INSERT INTO t (a) SELECT a FROM src;Postgres, SQLite 3.35+
INSERT INTO t (name) VALUES ('Ada') RETURNING id;Always include WHERE
UPDATE t SET a = 1 WHERE id = 9;DELETE FROM t; wipes the table
DELETE FROM t WHERE id = 9;PostgreSQL
INSERT INTO t (id, n) VALUES (1, 2)
ON CONFLICT (id) DO UPDATE SET n = EXCLUDED.n;MySQL. 8.0.19+ prefers aliases
INSERT INTO t (id, n) VALUES (1, 2)
ON DUPLICATE KEY UPDATE n = VALUES(n);DDL
Add constraints in the table, not later if you can
CREATE TABLE t (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);B-tree by default
CREATE INDEX t_name_idx ON t (name);Enforces uniqueness
CREATE UNIQUE INDEX t_email_uidx ON t (email);Syntax varies a lot by engine
ALTER TABLE t ADD COLUMN bio TEXT;Features
- Searchable SQL syntax reference
- Joins, data types, NULL, dates, strings, windows, indexes
- Postgres, MySQL, and SQLite notes where they diverge
- Copy any snippet
- Runs locally, no account
Common Use Cases
- Look up FULL OUTER JOIN syntax mid-query
- Remember COALESCE vs IFNULL vs ISNULL
- Copy a window-function skeleton
- Check date truncation names across engines
SQL is a family of dialects
The core SELECT FROM WHERE shape is shared. Types, functions, and identifier quotes are not. Postgres ILIKE is MySQL LIKE with a case-insensitive collation. SQLite is typeless compared with the others. When a snippet is engine-specific, the sheet says so.
Examples
SELECT * FROM t ORDER BY id LIMIT 10 OFFSET 20;SELECT * FROM t ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;Frequently Asked Questions
No. It is a practical sheet for the queries people write daily. Use your engine docs for GRANT, replication, and vendor extensions.
There is no database in the browser. Copy a snippet into your client, or pretty-print it in the SQL Formatter.
Tips
- Search for COALESCE, OVER, or RETURNING if you know the keyword but forgot the shape.