A reserved word is a keyword the SQL parser needs for its own grammar — SELECT, GROUP, ORDER, TABLE — and none of the five major dialects will let you use one as a column or table name unless you quote it correctly. Skip the quoting, or use the wrong quote character for the dialect you're on, and you get anything from an immediate syntax error to a query that runs cleanly and returns the wrong data.
The trap is that "reserved" doesn't mean the same list twice. PostgreSQL, MySQL, SQLite, SQL Server, and BigQuery each maintain their own reserved-word list, and each escapes a collision with a different quote character — double quotes, backticks, or square brackets. A column called user needs quoting in PostgreSQL and SQL Server, is a completely ordinary identifier in MySQL and BigQuery, and doesn't appear on SQLite's keyword list at all.
This post covers which words are reserved in which dialect, how to quote them correctly, and the specific cases — SQLite's double-quote fallback, MySQL's ANSI_QUOTES mode, SQL Server's QUOTED_IDENTIFIER setting — where the wrong quote mark doesn't error at all. It just silently changes what your statement means.
What makes a word "reserved" instead of just a keyword?
SQL parsers recognize hundreds of keywords, but only some of them are reserved. A non-reserved keyword like DATE or VALUE in PostgreSQL is known to the grammar but can still be used as a column or table name in most positions, because the parser can tell from context which one you mean. A reserved keyword like SELECT or GROUP can't be disambiguated that way — the grammar needs that exact token in that position, so the parser has no way to know whether you meant the keyword or a name.
PostgreSQL's own documentation lists three tiers: reserved, reserved-but-usable-as-a-function-or-type-name, and non-reserved. MySQL and SQL Server publish flatter reserved/non-reserved lists. BigQuery's list is short enough that a word is really just reserved or it isn't. SQLite doesn't separate the two at all — it maintains a single keyword list and recommends quoting any identifier that matches one of them, reserved or not, because the list keeps growing as SQLite adds features.
Why do reserved words break some queries and not others?
The most common failure mode is a hard syntax error — you use order unquoted somewhere PostgreSQL expects a plain identifier, the parser hits the ORDER keyword instead, and the statement refuses to run. That's the easy case: the error points at the exact spot, and quoting or renaming fixes it immediately.
The dangerous case is when the same quote character has two jobs — string literal and identifier — and a session setting decides which one wins. SQLite is the clearest example: if you double-quote a word that turns out not to match any column or table name in scope, SQLite doesn't error. It quietly treats the double-quoted token as a string literal instead, so your WHERE clause silently compares a column to a hardcoded string instead of the identifier you meant.