📖 Guide

SQL Cheat Sheet — Complete Reference

Complete SQL reference covering queries, joins, aggregation, subqueries, indexes, and database management.

137 commands across 12 categories

SELECT Queries

CommandDescription
SELECT * FROM table_name;
Select all columns from a table
SELECT col1, col2 FROM table_name;
Select specific columns
SELECT DISTINCT col FROM table_name;
Select unique values only (remove duplicates)
SELECT col AS alias FROM table_name;
e.g. SELECT first_name AS name, salary * 12 AS annual_salary FROM employees;
Rename a column in the output
SELECT * FROM t ORDER BY col ASC;
Sort results in ascending order (default)
SELECT * FROM t ORDER BY col DESC;
Sort results in descending order
SELECT * FROM t ORDER BY col1 ASC, col2 DESC;
Sort by multiple columns
SELECT * FROM t LIMIT n;
Return only the first N rows
SELECT * FROM t LIMIT n OFFSET m;
e.g. SELECT * FROM products ORDER BY id LIMIT 20 OFFSET 40;
Skip M rows, then return N rows (pagination)
SELECT * FROM t FETCH FIRST n ROWS ONLY;
SQL standard alternative to LIMIT

Filtering (WHERE)

CommandDescription
WHERE col = value
e.g. SELECT * FROM users WHERE status = 'active';
Filter rows where column equals a value
WHERE col != value / WHERE col <> value
Not equal comparison
WHERE col > / >= / < / <= value
Numeric comparison operators
WHERE col BETWEEN a AND b
e.g. SELECT * FROM orders WHERE total BETWEEN 100 AND 500;
Filter within a range (inclusive)
WHERE col IN (v1, v2, v3)
e.g. SELECT * FROM users WHERE country IN ('US', 'UK', 'DE');
Match any value in a list
WHERE col NOT IN (v1, v2)
Exclude specific values
WHERE col LIKE pattern
e.g. SELECT * FROM users WHERE email LIKE '%@gmail.com';
Pattern match with % (any chars) and _ (one char)
WHERE col ILIKE pattern
e.g. SELECT * FROM products WHERE name ILIKE '%phone%';
Case-insensitive LIKE (PostgreSQL)
WHERE col ~ regex
e.g. SELECT * FROM users WHERE email ~ '^[a-z]+@';
POSIX regex match (PostgreSQL)
WHERE col IS NULL / IS NOT NULL
Check for NULL values
WHERE cond1 AND cond2
Both conditions must be true
WHERE cond1 OR cond2
At least one condition must be true
WHERE NOT condition
Negate a condition
WHERE EXISTS (subquery)
e.g. SELECT * FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);
True if the subquery returns any rows

Joins

CommandDescription
INNER JOIN t2 ON t1.col = t2.col
e.g. SELECT u.name, o.total FROM users u INNER JOIN orders o ON u.id = o.user_id;
Return rows with matching values in both tables
LEFT JOIN t2 ON t1.col = t2.col
Return all rows from left table, matching rows from right (NULL if no match)
RIGHT JOIN t2 ON t1.col = t2.col
Return all rows from right table, matching rows from left
FULL OUTER JOIN t2 ON t1.col = t2.col
Return all rows from both tables (NULL where no match)
CROSS JOIN t2
Cartesian product — every combination of rows
t1 JOIN t2 USING (col)
e.g. SELECT * FROM orders JOIN products USING (product_id);
Join on a column with the same name in both tables
NATURAL JOIN t2
Automatically join on all columns with matching names
LEFT JOIN t2 ON ... WHERE t2.col IS NULL
e.g. SELECT u.* FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.id IS NULL;
Anti-join — find rows in t1 with no match in t2
Self-join: JOIN same_table AS alias
e.g. SELECT e.name, m.name AS manager FROM employees e LEFT JOIN employees m ON e.manager_id = m.id;
Join a table to itself

Aggregation (GROUP BY)

CommandDescription
COUNT(*)
Count all rows (including NULLs)
COUNT(col)
Count non-NULL values in a column
COUNT(DISTINCT col)
Count distinct non-NULL values
SUM(col)
Sum all values in a column
AVG(col)
Average of all values
MIN(col) / MAX(col)
Minimum or maximum value
GROUP BY col1, col2
e.g. SELECT country, COUNT(*) FROM users GROUP BY country;
Group rows by column values for aggregation
HAVING condition
e.g. SELECT country, COUNT(*) AS cnt FROM users GROUP BY country HAVING COUNT(*) > 10;
Filter groups (like WHERE but for aggregated results)
STRING_AGG(col, delimiter)
e.g. SELECT department, STRING_AGG(name, ', ') FROM employees GROUP BY department;
Concatenate values into a string (PostgreSQL)
ARRAY_AGG(col)
Collect values into an array (PostgreSQL)
BOOL_OR(col) / BOOL_AND(col)
Aggregate boolean values (PostgreSQL)

Subqueries

CommandDescription
WHERE col IN (SELECT ...)
e.g. SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE total > 1000);
Filter using results from a subquery
WHERE col = (SELECT ...)
e.g. SELECT * FROM products WHERE price > (SELECT AVG(price) FROM products);
Compare with a scalar subquery (must return one value)
SELECT (SELECT ...) AS col
Use a scalar subquery as a column
FROM (SELECT ...) AS alias
e.g. SELECT * FROM (SELECT user_id, COUNT(*) AS cnt FROM orders GROUP BY user_id) AS order_counts WHERE cnt > 5;
Use a subquery as a derived table
WITH cte AS (SELECT ...) SELECT ... FROM cte
e.g. WITH active_users AS ( SELECT * FROM users WHERE status = 'active' ) SELECT * FROM active_users WHERE created_at > '2024-01-01';
Common Table Expression (CTE) — named subquery
WITH RECURSIVE cte AS (...)
e.g. WITH RECURSIVE tree AS ( SELECT id, name, parent_id, 0 AS depth FROM categories WHERE parent_id IS NULL UNION ALL SELECT c.id, c.name, c.parent_id, t.depth + 1 FROM categories c JOIN tree t ON c.parent_id = t.id ) SELECT * FROM tree;
Recursive CTE for hierarchical/tree data
LATERAL (SELECT ...)
e.g. SELECT u.name, latest.total FROM users u, LATERAL (SELECT total FROM orders WHERE user_id = u.id ORDER BY created_at DESC LIMIT 1) AS latest;
Lateral subquery — can reference columns from preceding tables (PostgreSQL)

INSERT / UPDATE / DELETE

CommandDescription
INSERT INTO t (col1, col2) VALUES (v1, v2);
e.g. INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
Insert a single row
INSERT INTO t (cols) VALUES (...), (...), (...);
Insert multiple rows in one statement
INSERT INTO t (cols) SELECT ... FROM other;
Insert rows from a SELECT query
INSERT INTO t ... RETURNING *;
e.g. INSERT INTO users (name) VALUES ('Bob') RETURNING id, name;
Insert and return the inserted row(s) (PostgreSQL)
INSERT INTO t ... ON CONFLICT (col) DO NOTHING;
Upsert — skip if duplicate key (PostgreSQL)
INSERT INTO t ... ON CONFLICT (col) DO UPDATE SET col = EXCLUDED.col;
e.g. INSERT INTO users (email, name) VALUES ('a@b.com', 'Alice') ON CONFLICT (email) DO UPDATE SET name = EXCLUDED.name;
Upsert — update on duplicate key (PostgreSQL)
UPDATE t SET col = value WHERE condition;
e.g. UPDATE users SET status = 'inactive' WHERE last_login < '2023-01-01';
Update rows matching a condition
UPDATE t SET col1 = v1, col2 = v2 WHERE ...;
Update multiple columns at once
UPDATE t SET col = col + 1 WHERE ...;
Update using current value (increment)
UPDATE t SET ... FROM other WHERE t.id = other.id;
Update using a join (PostgreSQL)
UPDATE t SET ... RETURNING *;
Update and return the modified rows (PostgreSQL)
DELETE FROM t WHERE condition;
Delete rows matching a condition
DELETE FROM t;
Delete all rows (use TRUNCATE for large tables)
TRUNCATE TABLE t;
Remove all rows quickly (resets auto-increment, non-transactional in some DBs)
TRUNCATE TABLE t RESTART IDENTITY CASCADE;
Truncate and reset sequences, cascade to dependent tables (PostgreSQL)

Table Management

CommandDescription
CREATE TABLE t (col1 type, col2 type);
e.g. CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(255) UNIQUE, created_at TIMESTAMP DEFAULT NOW() );
Create a new table
CREATE TABLE IF NOT EXISTS t (...);
Create table only if it doesn't already exist
CREATE TABLE t AS SELECT ...;
Create a table from a query result
ALTER TABLE t ADD COLUMN col type;
Add a new column to an existing table
ALTER TABLE t DROP COLUMN col;
Remove a column from a table
ALTER TABLE t ALTER COLUMN col TYPE new_type;
Change a column's data type (PostgreSQL)
ALTER TABLE t ALTER COLUMN col SET NOT NULL;
Add a NOT NULL constraint
ALTER TABLE t ALTER COLUMN col SET DEFAULT value;
Set a default value for a column
ALTER TABLE t RENAME COLUMN old TO new;
Rename a column
ALTER TABLE t RENAME TO new_name;
Rename a table
DROP TABLE t;
Delete a table and all its data
DROP TABLE IF EXISTS t CASCADE;
Drop table if exists, including dependent objects

Indexes & Constraints

CommandDescription
CREATE INDEX idx_name ON t (col);
Create an index on a column (B-tree by default)
CREATE UNIQUE INDEX idx_name ON t (col);
Create a unique index (enforces uniqueness)
CREATE INDEX idx_name ON t (col1, col2);
Create a composite (multi-column) index
CREATE INDEX idx_name ON t USING GIN (col);
Create a GIN index (good for arrays, JSONB, full-text)
CREATE INDEX CONCURRENTLY idx_name ON t (col);
Create index without locking the table (PostgreSQL)
DROP INDEX idx_name;
Remove an index
PRIMARY KEY (col)
Define a primary key constraint
UNIQUE (col)
Ensure all values in a column are unique
NOT NULL
Prevent NULL values in a column
CHECK (condition)
e.g. CHECK (price > 0)
Enforce a custom constraint
REFERENCES other_table (col)
e.g. user_id INTEGER REFERENCES users (id) ON DELETE CASCADE
Foreign key constraint
ALTER TABLE t ADD CONSTRAINT name UNIQUE (col);
Add a constraint to an existing table
ALTER TABLE t DROP CONSTRAINT name;
Remove a constraint

String Functions

CommandDescription
LENGTH(s) / CHAR_LENGTH(s)
Get string length
UPPER(s) / LOWER(s)
Convert to uppercase or lowercase
TRIM(s) / LTRIM(s) / RTRIM(s)
Remove leading/trailing whitespace
SUBSTRING(s FROM start FOR length)
e.g. SUBSTRING('Hello World' FROM 1 FOR 5) -- 'Hello'
Extract part of a string
POSITION(sub IN s)
Find position of substring (1-indexed)
REPLACE(s, from, to)
Replace all occurrences of a substring
CONCAT(s1, s2, ...) / s1 || s2
Concatenate strings
LEFT(s, n) / RIGHT(s, n)
Get first/last N characters
LPAD(s, length, fill) / RPAD(s, length, fill)
e.g. LPAD('42', 5, '0') -- '00042'
Pad string to a specified length
INITCAP(s)
Capitalize first letter of each word (PostgreSQL)
REGEXP_REPLACE(s, pattern, replacement)
e.g. REGEXP_REPLACE('abc123', '[0-9]+', 'NUM')
Replace using regex (PostgreSQL)
SPLIT_PART(s, delimiter, n)
e.g. SPLIT_PART('a.b.c', '.', 2) -- 'b'
Get Nth part of a delimited string (PostgreSQL)

Date Functions

CommandDescription
NOW() / CURRENT_TIMESTAMP
Current date and time
CURRENT_DATE
Current date (without time)
CURRENT_TIME
Current time (without date)
EXTRACT(field FROM timestamp)
e.g. EXTRACT(YEAR FROM created_at) EXTRACT(DOW FROM NOW()) -- day of week
Get a specific part of a date/time
DATE_TRUNC(field, timestamp)
e.g. DATE_TRUNC('month', created_at) -- start of month
Truncate to specified precision (PostgreSQL)
timestamp + INTERVAL '1 day'
e.g. NOW() - INTERVAL '30 days' NOW() + INTERVAL '2 hours'
Add/subtract intervals from timestamps
AGE(timestamp1, timestamp2)
e.g. AGE(NOW(), created_at)
Difference between two timestamps as interval (PostgreSQL)
TO_CHAR(timestamp, format)
e.g. TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS')
Format a timestamp as a string (PostgreSQL)
TO_TIMESTAMP(text, format)
Parse a string into a timestamp (PostgreSQL)
date1 - date2
Difference between two dates (returns integer days in PostgreSQL)
GENERATE_SERIES(start, stop, step)
e.g. SELECT generate_series('2024-01-01'::date, '2024-12-31'::date, '1 month'::interval);
Generate a series of dates (PostgreSQL)

Window Functions

CommandDescription
ROW_NUMBER() OVER (ORDER BY col)
e.g. SELECT name, salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rank FROM employees;
Assign sequential row numbers
RANK() OVER (ORDER BY col)
Rank with gaps for ties (1, 2, 2, 4)
DENSE_RANK() OVER (ORDER BY col)
Rank without gaps for ties (1, 2, 2, 3)
NTILE(n) OVER (ORDER BY col)
e.g. NTILE(4) OVER (ORDER BY salary) AS quartile
Divide rows into N roughly equal groups
OVER (PARTITION BY col ORDER BY col2)
e.g. SELECT department, name, salary, RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank FROM employees;
Window function partitioned by groups
SUM(col) OVER (ORDER BY col ROWS BETWEEN ...)
e.g. SUM(amount) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
Running/cumulative sum with frame specification
LAG(col, n, default) OVER (...)
e.g. LAG(salary, 1) OVER (ORDER BY hire_date) AS prev_salary
Access a value from N rows before the current row
LEAD(col, n, default) OVER (...)
Access a value from N rows after the current row
FIRST_VALUE(col) OVER (...)
Get the first value in the window frame
LAST_VALUE(col) OVER (...)
Get the last value in the window frame

Common Patterns

CommandDescription
CASE WHEN cond THEN val ... ELSE default END
e.g. SELECT name, CASE WHEN salary > 100000 THEN 'high' WHEN salary > 50000 THEN 'mid' ELSE 'low' END AS bracket FROM employees;
Conditional logic in SQL
COALESCE(val1, val2, ...)
e.g. SELECT COALESCE(nickname, first_name, 'Anonymous') AS display_name FROM users;
Return first non-NULL value
NULLIF(a, b)
e.g. SELECT total / NULLIF(count, 0) AS average FROM stats;
Return NULL if a equals b (useful to avoid division by zero)
CAST(expr AS type) / expr::type
e.g. SELECT '42'::INTEGER; SELECT CAST('2024-01-01' AS DATE);
Type casting (PostgreSQL supports :: shorthand)
SELECT ... UNION ALL SELECT ...
Combine results from two queries (keeps duplicates)
SELECT ... UNION SELECT ...
Combine results and remove duplicates
SELECT ... INTERSECT SELECT ...
Return rows common to both queries
SELECT ... EXCEPT SELECT ...
Return rows in first query but not in second
EXPLAIN ANALYZE SELECT ...;
Show query execution plan with actual timings
CREATE VIEW v AS SELECT ...;
e.g. CREATE VIEW active_users AS SELECT * FROM users WHERE status = 'active';
Create a reusable named query
CREATE MATERIALIZED VIEW mv AS SELECT ...;
Create a cached view (PostgreSQL) — must be refreshed manually
REFRESH MATERIALIZED VIEW mv;
Refresh data in a materialized view
BEGIN; ... COMMIT; / ROLLBACK;
e.g. BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 2; COMMIT;
Transaction — group statements atomically

More Guides

🌿
Git Commands
Complete Git command reference — from basics to advanced workflows. Searchable, with examples.
📝
Vim Commands
Complete Vim/Vi command reference — modes, motions, editing, search, and advanced features.
🐳
Docker Commands
Complete Docker & Docker Compose command reference — containers, images, volumes, networks, and orchestration.
🔤
Regex Reference
Complete regular expression reference — syntax, patterns, quantifiers, groups, lookaheads, and common recipes.
🐧
Linux Commands
Complete Linux/Bash command reference — file management, text processing, networking, system admin, and shell scripting.
☸️
Kubernetes Commands
Complete Kubernetes & kubectl command reference — pods, deployments, services, configmaps, and cluster management.
🐍
Python Reference
Complete Python reference — syntax, data structures, string methods, file I/O, comprehensions, and common patterns.
🌐
Nginx Reference
Complete Nginx configuration reference — server blocks, locations, proxying, SSL, load balancing, and caching.
🔐
SSH Commands
Complete SSH reference — connections, key management, tunneling, config, SCP/SFTP, and security hardening.
👷
Jenkins Reference
Complete Jenkins reference — pipeline syntax, Jenkinsfile, plugins, CLI, agents, and CI/CD patterns.
☁️
AWS CLI Reference
Complete AWS CLI reference — EC2, S3, IAM, Lambda, ECS, RDS, CloudFormation, and common operations.
🐹
Go Reference
Complete Go (Golang) reference — syntax, types, functions, concurrency, error handling, and common patterns.
💠
PowerShell Reference
Complete PowerShell reference — cmdlets, pipelines, scripting, file operations, remote management, and Active Directory.
💾
Redis Commands
Complete Redis command reference — strings, hashes, lists, sets, sorted sets, pub/sub, transactions, and server management.
🏗️
Terraform Commands
Complete Terraform reference — init, plan, apply, state management, modules, workspaces, and HCL syntax.
⚙️
Ansible Commands
Complete Ansible reference — playbooks, modules, inventory, roles, vault, and ad-hoc commands.

📖 Free, searchable command reference. Bookmark this page for quick access.