This SQL cheat sheet covers the most important SQL commands, syntax patterns, and quick-reference tables. Whether you are just starting out or need a refresher before an interview, bookmark this page. Every example is tested on MySQL, PostgreSQL, and T-SQL. Use our free online SQL formatter to clean up any query you write.
SQL Cheat Sheet — Quick Reference Guide for Beginners
Table of Contents
1. Basic SQL Commands — Quick Reference
| Command | Description | Example |
|---|---|---|
SELECT | Retrieve data from a table | SELECT * FROM users; |
INSERT | Add new rows | INSERT INTO users (name) VALUES ('Alice'); |
UPDATE | Modify existing rows | UPDATE users SET name='Bob' WHERE id=1; |
DELETE | Remove rows | DELETE FROM users WHERE id=1; |
CREATE TABLE | Create a new table | CREATE TABLE users (id INT, name TEXT); |
ALTER TABLE | Modify table structure | ALTER TABLE users ADD email TEXT; |
DROP TABLE | Delete a table | DROP TABLE users; |
TRUNCATE | Delete all rows (fast) | TRUNCATE TABLE users; |
2. SELECT — Retrieving Data
-- Select all columns
SELECT * FROM employees;
-- Select specific columns
SELECT first_name, last_name, salary FROM employees;
-- Distinct values (no duplicates)
SELECT DISTINCT department FROM employees;
-- Limit results (MySQL/PostgreSQL)
SELECT * FROM employees LIMIT 10;
-- Limit results (T-SQL)
SELECT TOP 10 * FROM employees;
-- Sort results
SELECT * FROM employees ORDER BY salary DESC;
-- Sort by multiple columns
SELECT * FROM employees ORDER BY department ASC, salary DESC;
3. WHERE — Filtering Rows
| Operator | Description | Example |
|---|---|---|
= | Equal | WHERE dept = 'Engineering' |
!= or <> | Not equal | WHERE status != 'closed' |
>, <, >=, <= | Greater/less than | WHERE salary > 50000 |
BETWEEN | Range (inclusive) | WHERE age BETWEEN 18 AND 65 |
LIKE | Pattern match | WHERE email LIKE '%@gmail.com' |
IN | Match any in list | WHERE dept IN ('Sales','HR') |
IS NULL | Null check | WHERE manager_id IS NULL |
AND / OR | Combine conditions | WHERE dept='Eng' AND salary>50k |
-- Complex filtering example
SELECT first_name, last_name, salary
FROM employees
WHERE department = 'Engineering'
AND salary > 60000
AND hire_date >= '2024-01-01'
AND (status = 'active' OR status = 'on_leave')
ORDER BY salary DESC;
4. JOIN — Combining Tables
| Type | Description |
|---|---|
INNER JOIN | Returns rows with matches in both tables |
LEFT JOIN | Returns all left-table rows + matches from right |
RIGHT JOIN | Returns all right-table rows + matches from left |
FULL OUTER JOIN | Returns all rows from both tables |
CROSS JOIN | Cartesian product (every combination) |
SELF JOIN | Join a table to itself |
-- INNER JOIN: employees with their department name
SELECT e.name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.id;
-- LEFT JOIN: all employees even if no department
SELECT e.name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.id;
-- SELF JOIN: employee and their manager
SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.id;
Format Your SQL Automatically
Paste messy SQL with complex JOINs — get clean, indented output instantly.
Format SQL Now →5. GROUP BY — Aggregating Data
-- Count employees per department
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department;
-- Aggregate functions
SELECT
department,
COUNT(*) AS emp_count,
AVG(salary) AS avg_salary,
MAX(salary) AS max_salary,
MIN(salary) AS min_salary,
SUM(salary) AS total_payroll
FROM employees
GROUP BY department;
-- Filter groups with HAVING (after aggregation)
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 70000;
-- Common aggregate functions
-- COUNT, SUM, AVG, MAX, MIN, STRING_AGG, ARRAY_AGG
6. Subqueries & CTEs
-- Subquery in WHERE
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);
-- Subquery in FROM
SELECT dept, avg_sal
FROM (SELECT department AS dept, AVG(salary) AS avg_sal FROM employees GROUP BY department) sub
WHERE avg_sal > 60000;
-- CTE (Common Table Expression) — clearer than subqueries
WITH dept_stats AS (
SELECT department, AVG(salary) AS avg_sal
FROM employees
GROUP BY department
)
SELECT e.name, e.salary, ds.avg_sal
FROM employees e
JOIN dept_stats ds ON e.department = ds.department
WHERE e.salary > ds.avg_sal;
7. Window Functions
-- ROW_NUMBER: rank rows within a partition
SELECT name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rank
FROM employees;
-- RANK vs DENSE_RANK (RANK skips ties, DENSE_RANK does not)
SELECT name, salary,
RANK() OVER (ORDER BY salary DESC) AS rank,
DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank
FROM employees;
-- LAG / LEAD: access previous/next row
SELECT name, hire_date,
LAG(name) OVER (ORDER BY hire_date) AS hired_before,
LEAD(name) OVER (ORDER BY hire_date) AS hired_after
FROM employees;
-- Running total with SUM OVER
SELECT order_date, amount,
SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM orders;
8. DDL — Creating & Modifying Tables
-- Create table with constraints
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
department_id INT REFERENCES departments(id),
salary DECIMAL(10,2) CHECK (salary > 0),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Add column
ALTER TABLE employees ADD COLUMN phone VARCHAR(20);
-- Drop column
ALTER TABLE employees DROP COLUMN phone;
-- Rename column (PostgreSQL)
ALTER TABLE employees RENAME COLUMN name TO full_name;
-- Create index
CREATE INDEX idx_employees_dept ON employees(department_id);
-- Create unique index
CREATE UNIQUE INDEX idx_employees_email ON employees(email);
9. DML — Insert, Update, Delete
-- Insert single row
INSERT INTO employees (name, email, department_id, salary)
VALUES ('Alice Chen', 'alice@company.com', 3, 75000);
-- Insert multiple rows
INSERT INTO employees (name, email, department_id, salary)
VALUES
('Bob Smith', 'bob@company.com', 2, 65000),
('Carol Wu', 'carol@company.com', 3, 82000);
-- Insert from SELECT
INSERT INTO employees_archive
SELECT * FROM employees WHERE status = 'terminated';
-- Update rows
UPDATE employees
SET salary = salary * 1.1, updated_at = NOW()
WHERE department_id = 3 AND performance = 'exceeds';
-- Delete rows
DELETE FROM employees
WHERE status = 'terminated' AND updated_at < '2024-01-01';
10. Common Data Types
| Type | MySQL | PostgreSQL | T-SQL |
|---|---|---|---|
| Integer | INT, BIGINT | INTEGER, BIGINT | INT, BIGINT |
| Decimal | DECIMAL(10,2) | NUMERIC(10,2) | DECIMAL(10,2) |
| String | VARCHAR(255) | VARCHAR(255) | NVARCHAR(255) |
| Text | TEXT | TEXT | NVARCHAR(MAX) |
| Boolean | TINYINT(1) | BOOLEAN | BIT |
| Date/Time | DATETIME | TIMESTAMP | DATETIME2 |
| Auto-increment | AUTO_INCREMENT | SERIAL | IDENTITY(1,1) |
| JSON | JSON | JSONB | NVARCHAR(MAX) |
FAQ
What are the basic SQL commands every beginner should know?
Start with SELECT, INSERT, UPDATE, and DELETE — the four fundamental operations. Then learn WHERE (filtering), JOIN (combining tables), GROUP BY (aggregation), and ORDER BY (sorting). These 8 commands cover 90% of daily SQL work.
How do I format SQL queries to make them readable?
Use uppercase for keywords, put each clause on a new line, indent subqueries, and format column lists vertically. Or use SQLFormat.io to auto-format any query in one click — 15+ dialects supported.
What is the difference between INNER JOIN and LEFT JOIN?
INNER JOIN returns only rows with matches in both tables. LEFT JOIN returns all rows from the left table plus matching rows from the right — unmatched right columns get NULL. Use LEFT JOIN when you need all rows from the main table regardless of matches.