SQL Cheat Sheet

Essential SQL commands in one page. SELECT, JOIN, WHERE, GROUP BY, subqueries, window functions, and data manipulation — for MySQL, PostgreSQL, and SQLite.

SELECT Basics WHERE & Filtering ORDER BY & GROUP BY JOINs Aggregate Functions Data Manipulation Table Operations Subqueries & Window Functions

SELECT Basics

SELECT * FROM users Select all columns from table
SELECT name, email FROM users Select specific columns
SELECT DISTINCT city FROM users Select unique values only
SELECT COUNT(*) FROM users Count all rows
SELECT * FROM users LIMIT 10 Limit results to 10 rows
SELECT * FROM users LIMIT 10 OFFSET 20 Skip 20, then take 10 (pagination)
SELECT name AS full_name FROM users Rename column in output (alias)

WHERE & Filtering

WHERE age > 18 Greater than
WHERE age BETWEEN 18 AND 65 Range (inclusive)
WHERE name LIKE "J%" Pattern match (% = any chars, _ = one char)
WHERE name ILIKE "j%" Case-insensitive LIKE (PostgreSQL)
WHERE city IN ("NYC", "LA", "SF") Match any in list
WHERE email IS NULL Check for NULL
WHERE email IS NOT NULL Check for non-NULL
WHERE age > 18 AND city = "NYC" Multiple conditions (AND)
WHERE age > 18 OR city = "NYC" Either condition (OR)
WHERE NOT (age < 18) Negate condition

ORDER BY & GROUP BY

ORDER BY name ASC Sort ascending (default)
ORDER BY created_at DESC Sort descending (newest first)
ORDER BY city, name Sort by multiple columns
GROUP BY city Group rows by column value
GROUP BY city HAVING COUNT(*) > 5 Filter groups (like WHERE for groups)
SELECT city, COUNT(*), AVG(age) FROM users GROUP BY city Aggregate per group

JOINs

INNER JOIN orders ON users.id = orders.user_id Only matching rows from both tables
LEFT JOIN orders ON users.id = orders.user_id All from left + matching from right (NULL if no match)
RIGHT JOIN orders ON users.id = orders.user_id All from right + matching from left
FULL OUTER JOIN orders ON users.id = orders.user_id All rows from both (NULLs where no match)
CROSS JOIN colors Every combination of rows (cartesian product)
LEFT JOIN orders USING (user_id) Shorthand when column names match

Aggregate Functions

COUNT(*) Count all rows (including NULLs)
COUNT(DISTINCT city) Count unique values
SUM(amount) Sum of all values
AVG(price) Average value
MIN(created_at) Minimum value
MAX(price) Maximum value
GROUP_CONCAT(name) Concatenate values (MySQL)
STRING_AGG(name, ', ') Concatenate values (PostgreSQL)

Data Manipulation

INSERT INTO users (name, email) VALUES ("Jo", "[email protected]") Insert a row
INSERT INTO users (name) VALUES ("A"), ("B"), ("C") Insert multiple rows
UPDATE users SET name = "Jo" WHERE id = 1 Update rows matching condition
DELETE FROM users WHERE id = 1 Delete rows matching condition
TRUNCATE TABLE users Delete all rows (fast, no logging)

Table Operations

CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100)) Create table
ALTER TABLE users ADD COLUMN age INT Add column
ALTER TABLE users DROP COLUMN age Remove column
ALTER TABLE users RENAME COLUMN name TO full_name Rename column
DROP TABLE users Delete table and all data
CREATE INDEX idx_email ON users(email) Create index for faster queries

Subqueries & Window Functions

WHERE id IN (SELECT user_id FROM orders) Subquery in WHERE
SELECT *, (SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id) AS order_count FROM users Correlated subquery
WITH cte AS (SELECT ...) SELECT * FROM cte Common Table Expression (CTE)
ROW_NUMBER() OVER (ORDER BY created_at) Sequential row number
RANK() OVER (PARTITION BY dept ORDER BY salary DESC) Rank within groups (gaps on ties)
LAG(price, 1) OVER (ORDER BY date) Previous row value
SUM(amount) OVER (ORDER BY date ROWS UNBOUNDED PRECEDING) Running total

Try It Live

Test these patterns with our free SQL Formatter. No signup needed.

Open SQL Formatter →
Step-by-Step Guide

How to Convert CSV to JSON

Read Guide →

More Cheat Sheets