SQL Cheat Sheet — Syntax & Query Reference

SELECT to window functions, transactions & indexes — with copy-ready queries.

A free, searchable SQL syntax cheat sheet covering basic queries (SELECT, ORDER BY, LIMIT, DISTINCT), filtering (WHERE, AND/OR, IN, BETWEEN, LIKE, IS NULL), all four join types plus self joins, aggregate functions & GROUP BY/HAVING, window functions (ROW_NUMBER, RANK, LEAD/LAG), INSERT/UPDATE/DELETE, transactions (BEGIN/COMMIT/ROLLBACK), table creation & constraints (CREATE TABLE, CHECK, DEFAULT, PRIMARY/FOREIGN KEY), indexes & query performance (CREATE INDEX, EXPLAIN), subqueries, Common Table Expressions (CTEs) and common string/date/CASE/COALESCE functions — each with a copy-ready query and a real worked example. Also visualizes SQL's actual execution order (FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT) and includes quick-reference comparison tables for join types, aggregate functions, and PostgreSQL vs MySQL vs SQL Server syntax differences. Complements the site's SQL Formatter/Beautifier: this page teaches the syntax, the Formatter cleans up a query you already wrote. Runs fully in your browser, no sign-up, no API.

About SQL Cheat Sheet — Syntax & Query Reference

SQL Cheat Sheet — Syntax & Query Reference features

Best practices

Always test UPDATE and DELETE with a SELECT first

Write the exact same WHERE condition as a SELECT * and check the rows returned match your expectation, before swapping it for UPDATE or DELETE. A forgotten WHERE clause on DELETE removes every row in the table.

Table aliases make joins much easier to read

Giving each table a short alias (customers AS c, orders AS o) lets you write c.name and o.total instead of the full table name every time — especially useful once you're joining three or more tables.

NULL is not the same as an empty string or zero

NULL means “no value at all” — it isn't equal to '', 0, or even another NULL. That's why you need IS NULL instead of = NULL, and why SUM/AVG silently skip NULL values instead of treating them as 0.

WHERE filters rows, HAVING filters groups

WHERE runs before GROUP BY and can't reference an aggregate like COUNT(*). HAVING runs after grouping and is the only place you can filter on an aggregate result.

Never build a query by pasting user input into a string

Combining user input directly into a query string (e.g. "SELECT * FROM users WHERE name = '" + input + "'") opens the door to SQL injection — a malicious input can change what the query actually does. Always use parameterized queries / prepared statements (placeholders like ? or $1 that your database driver fills in safely) instead.

Wrap a risky UPDATE or DELETE in a transaction

BEGIN a transaction, run the UPDATE or DELETE, check the affected rows look right, then COMMIT — or ROLLBACK immediately if something looks wrong. This gives you an undo button that a plain UPDATE/DELETE never has.

Frequently asked questions

What is SQL used for?

SQL (Structured Query Language) is used to store, retrieve, filter, combine and change data in a relational database — reading customer records, calculating totals, joining related tables together, and inserting, updating or deleting rows.

What is the difference between this page and the SQL Formatter?

This page is a syntax reference — it explains how to write each type of statement (SELECT, JOIN, GROUP BY, INSERT, and so on) with a copy-ready example. The SQL Formatter/Beautifier takes a query you've already written and reformats it — consistent indentation, capitalization and line breaks — without changing what it does.

In what order does SQL actually run a query?

Not top to bottom. The real order is FROM (and JOIN) → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT. This is why WHERE can't reference a column alias defined in SELECT (WHERE runs before SELECT exists yet), while ORDER BY can (it runs after).

What is the difference between WHERE and HAVING?

WHERE filters individual rows before any grouping happens, and can't reference an aggregate function like COUNT() or SUM(). HAVING filters AFTER GROUP BY has combined rows into groups, and is the only place you can filter based on an aggregate result, like HAVING COUNT(*) > 10.

What is the difference between INNER JOIN and LEFT JOIN?

INNER JOIN only returns rows where the join condition matches in both tables. LEFT JOIN returns every row from the left (first) table regardless of whether it has a match, filling in NULL for the right table's columns when there's no match.

What does GROUP BY do in SQL?

GROUP BY splits the result into groups of rows that share the same value in one or more columns, so an aggregate function like COUNT(), SUM() or AVG() is calculated separately for each group instead of across the whole table.

What are SQL window functions and when do I need them?

A window function (ROW_NUMBER(), RANK(), LEAD()/LAG(), or an aggregate used with OVER()) calculates a value across a group of rows WITHOUT collapsing them into one row per group, the way GROUP BY does. Reach for one when you need a running total, a rank, or a comparison to a neighbouring row, while still seeing every individual row.

What is a SQL transaction and why does it matter?

A transaction (BEGIN … COMMIT, or ROLLBACK to cancel) bundles several statements into one all-or-nothing unit. Without one, a crash or error partway through a multi-step change (like moving money between two accounts) can leave your data in an inconsistent state — a transaction guarantees every statement in it succeeds together, or none of them take effect at all.

What is a CTE (Common Table Expression) in SQL?

A CTE, written WITH name AS (...), names a subquery up front so the rest of the query can reference it by name. It does the same job as a subquery nested in FROM, but reads top-to-bottom like a plan instead of nesting deeply — and can even reference itself (a recursive CTE) to walk a hierarchy or generate a sequence.

How do I make a slow SQL query faster?

Start with EXPLAIN (or EXPLAIN ANALYZE for real timings) to see how the database is actually running your query. The most common fix is CREATE INDEX on the columns you filter, join or sort on most often — indexes let the database jump straight to matching rows instead of scanning the whole table.

How do I filter by a range of values in SQL?

Use BETWEEN for a continuous range (WHERE total BETWEEN 100 AND 500), or IN for a specific list of values (WHERE city IN ('Mumbai', 'Delhi')). Both are inclusive of the values listed.

What is a subquery in SQL?

A subquery is a SELECT statement nested inside another query. It can appear inside WHERE (to filter using a computed value), inside FROM (treated as a temporary table), or inside SELECT itself, and always runs before the outer query uses its result.

How do I safely test an UPDATE or DELETE before running it?

Run the exact same WHERE condition as a plain SELECT * first, and check the returned rows are exactly what you expect to change or remove. Only then swap SELECT * for UPDATE ... SET ... or DELETE FROM — or better, wrap it in a transaction (BEGIN … COMMIT/ROLLBACK) so you can undo it if something looks wrong.

What is the difference between UNION and UNION ALL?

UNION combines the results of two SELECT statements and removes any exact duplicate rows. UNION ALL does the same but keeps duplicates, which makes it faster since it skips the de-duplication step.

Why doesn't WHERE email = NULL work?

NULL means “no value at all”, so it can never be equal (=) to anything, including another NULL. SQL requires the special IS NULL (or IS NOT NULL) syntax to test for missing values instead. Use COALESCE(column, fallback) to substitute a default value inside a calculation instead.

Is SQL the same in every database?

The core syntax (SELECT, WHERE, JOIN, GROUP BY, INSERT, UPDATE, DELETE) is shared across MySQL, PostgreSQL, SQL Server and SQLite. Small differences exist — for example LIMIT (PostgreSQL/MySQL) versus TOP (SQL Server) for capping rows, or || versus CONCAT() for joining text — the comparison table on this page covers the most common ones.

How do I prevent SQL injection?

Never build a query by pasting user input directly into a string. Use parameterized queries / prepared statements — placeholders like ? or $1 that your database driver fills in safely — so user input is always treated as data, never as part of the SQL itself.

Is this SQL cheat sheet free to use?

Yes — it is 100% free with no sign-up, no login and no limits. The whole reference runs in your browser, so you can search, read and bookmark it without creating an account.

Related tools — Guides & Tutorials