SQL Syntax Cheatsheet

Search SQL keywords, clauses and functions with syntax and dialect notes.

A searchable SQL reference covering ANSI syntax plus MySQL, PostgreSQL, SQLite and SQL Server variations, with the syntax pattern, a description and dialect notes for queries, joins, DML, DDL and window functions. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between WHERE and HAVING?

WHERE filters individual rows before grouping, while HAVING filters groups after aggregation. You use HAVING to keep, for example, only the groups whose COUNT(*) is greater than five, which WHERE cannot do because the aggregate is not yet computed.

This is a searchable SQL syntax cheatsheet covering the keywords, clauses and functions you use every day. Each entry gives the syntax pattern, a one-line description, and — where the dialects diverge — notes for MySQL, PostgreSQL, SQLite and SQL Server, so you can write portable queries or adapt one to a specific engine.

How it works

SQL is largely standardised by ANSI, but every database adds its own spellings for common tasks. The reference is grouped so you can browse by area: Query (SELECT, DISTINCT, CTEs), Clause (WHERE, GROUP BY, HAVING, ORDER BY, LIMIT), Join types, DML (INSERT, UPDATE, DELETE, upsert), DDL (CREATE, ALTER, DROP, indexes), aggregate and scalar functions, window functions and transactions. Search matches the keyword, the syntax and the dialect notes, so a query for “pagination” or “auto increment” surfaces the right entries even if you do not remember the exact keyword.

Logical execution order — the most useful thing in SQL

The single most useful thing to internalise is the order in which SQL logically executes a SELECT:

FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT

This order explains several common confusions:

  • A column alias defined in SELECT cannot be used in WHERE (SELECT hasn’t run yet), but can be used in ORDER BY (which runs after).
  • WHERE filters individual rows before grouping; HAVING filters groups after aggregation. You cannot put an aggregate like COUNT(*) inside a WHERE clause.
  • DISTINCT runs after SELECT builds the output column list but before ORDER BY.

Key dialect differences at a glance

FeatureMySQLPostgreSQLSQLiteSQL Server
Auto-incrementAUTO_INCREMENTSERIAL / GENERATEDAUTOINCREMENTIDENTITY
UpsertINSERT ... ON DUPLICATE KEY UPDATEINSERT ... ON CONFLICT DO UPDATEINSERT OR REPLACEMERGE
PaginationLIMIT n OFFSET mLIMIT n OFFSET mLIMIT n OFFSET mOFFSET n ROWS FETCH NEXT m ROWS ONLY
Full outer joinNot supportedSupportedNot supportedSupported
String concatCONCAT(a, b)a || ba || ba + b
Current timestampNOW()NOW()datetime('now')GETDATE()

Tips and gotchas

Watch the dialect notes for the big traps: FULL OUTER JOIN is missing in MySQL and SQLite, auto-increment is spelled four different ways, and upsert syntax differs by engine.

Common mistakes:

  • Using a SELECT alias in WHERE instead of HAVING or a subquery.
  • Forgetting that NULL != NULL — use IS NULL and IS NOT NULL, not = NULL.
  • LIKE with a leading wildcard (LIKE '%term') cannot use an index and causes a full scan.
  • Mixing implicit and explicit joins in the same query — always use explicit JOIN ... ON.

Everything runs in your browser; this tool never connects to a database or uploads your input.