Sharon Ben-Moshe is the founder of sqlfmt, a browser-based SQL formatter and validator with misspelled-keyword suggestions across PostgreSQL, MySQL, SQLite, SQL Server, and BigQuery.
Single quotes are for string values, double quotes are for identifiers — but MySQL, SQL Server, and BigQuery bend the rule. The full guide, with examples.
Quick answer
In standard SQL, single quotes ('text') delimit string and date literals, while double quotes ("name") delimit identifiers like column and table names. So use single quotes for values you're comparing or inserting, and double quotes only when an identifier needs special characters, spaces, or case sensitivity. MySQL is the exception — it treats double quotes as strings unless ANSI_QUOTES mode is on.
FAQs
Why does "column does not exist" appear when I use double quotes?
Because double quotes mean "identifier," not "string," in PostgreSQL, SQLite, and SQL Server. When you write WHERE name = "John", the database looks for a column named John instead of comparing against the text John. Switch the value to single quotes ('John') and the error goes away.
Can I use double quotes for strings in MySQL?
Yes, by default MySQL accepts double quotes as string delimiters, so "text" and 'text' both work. But it's not portable — the same query fails in PostgreSQL. If you enable ANSI_QUOTES mode, MySQL treats double quotes as identifiers like the standard. Use single quotes for strings to stay portable.
How do I escape a single quote inside a SQL string?
Double it. To store O'Brien, write 'O''Brien' — two single quotes in a row represent one literal apostrophe. This is the SQL-standard escape and works in every major database. Avoid backslash escaping, which is non-standard and depends on database settings.
What are backticks and square brackets for in SQL?
They're alternative identifier delimiters. MySQL and BigQuery use backticks (`table_name`) to quote identifiers, while SQL Server uses square brackets ([table name]). They serve the same purpose as standard double-quoted identifiers: wrapping a name that contains spaces, special characters, or a reserved keyword.
Try it now
Paste your SQL into sqlfmt — format, validate, and catch typos free in your browser.
In SQL, single quotes and double quotes mean two completely different things. Single quotes wrap string and date literals — the actual values you compare, insert, or filter on. Double quotes wrap identifiers — the names of tables, columns, and other database objects. Mixing them up is one of the most common sources of confusing SQL errors.
That's the ANSI standard, and PostgreSQL, SQLite, Oracle, and SQL Server all follow it. MySQL is the odd one out, and BigQuery has its own twist. This guide covers the rule, the per-dialect exceptions, and the classic "column does not exist" error that double quotes cause.
What's the difference between single and double quotes in SQL?
Single quotes create a string literal: a value. Double quotes create a quoted identifier: a name. The parser decides what a token means by which quote surrounds it, so 'users' is the five-character text users, while "users" is the table or column called users.
Single = value, double = name
-- 'active' is a string value; "status" is a column nameSELECT "status"FROM ordersWHERE "status" = 'active';
Most of the time you don't quote identifiers at all — unquoted names work fine. You only need double quotes for identifiers that break the normal rules, which we'll get to.
Single quotes: string and date literals
Use single quotes for every text value, date, and timestamp literal. This is non-negotiable across dialects — the PostgreSQL lexical structure docs spell out that string constants are written in single quotes. To include a literal single quote inside a string, double it.
Escaping a single quote by doubling it
INSERT INTO authors (name, bio)VALUES ('O''Brien', 'Writes about SQL since ''99.');
O''Brien stores the value O'Brien. Doubling the quote is the standard escape and works everywhere; never use a backslash to escape quotes in portable SQL.
Double quotes: identifiers that need protecting
Reach for double quotes around an identifier only when it: contains spaces or special characters, collides with a reserved keyword, or needs to preserve exact case. PostgreSQL folds unquoted identifiers to lowercase, so "Order" and order are different objects once you quote them.
When double-quoting an identifier is required
-- Column literally named "first name" with a space,-- and a column that clashes with the reserved word "order"SELECT "first name", "order"FROM "user profiles";
A word of advice: needing double quotes is usually a smell. Name objects in lowercase snake_case with no spaces or reserved words, and you'll rarely type a double quote around an identifier again.
Where the dialects disagree
MySQL breaks the standard by default: it accepts double quotes as an alternative way to write string literals, and uses backticks for identifiers. The MySQL string-literal docs confirm both "text" and 'text' are strings unless you enable ANSI_QUOTES mode, which makes double quotes mean identifiers like everywhere else.
PostgreSQL / SQLite / Oracle: single = string, double = identifier (the standard).
MySQL / MariaDB: single = string, double = string too (by default), backticks = identifier.
SQL Server (T-SQL): single = string, double = identifier (with QUOTED_IDENTIFIER ON, the default), square brackets [name] also delimit identifiers.
BigQuery: single or double quotes both make strings; backticks delimit identifiers like `project.dataset.table`.
The portable habit: always single-quote strings, always backtick-or-bracket per dialect for the rare quoted identifier, and never rely on double quotes for strings even where MySQL allows it.
The classic error: "column does not exist"
The single most common quoting bug: using double quotes around a string value in PostgreSQL. The parser reads it as an identifier and looks for a column by that name.
The error is misleading because nothing is literally named John — but Postgres has no way to know you meant a string. If you see "column ... does not exist" pointing at something that's obviously a value, check your quotes first.
Checklist: getting SQL quotes right
Any text, date, or timestamp value → single quotes.
An apostrophe inside a string → double the single quote ('').
A normal column or table name → no quotes at all.
An identifier with spaces, special characters, or a reserved word → double quotes (Postgres/SQLite/SQL Server), backticks (MySQL/BigQuery).
Seeing "column X does not exist" on something that's a value? You double-quoted a string — switch to single quotes.
Writing portable SQL? Never use double quotes for strings, even though MySQL allows it.
Wrapping up
Single quotes for values, double quotes for names, and a per-dialect twist for MySQL and BigQuery — get that straight and most quoting errors disappear. sqlfmt validates your SQL per dialect and flags the mismatched-quote and unknown-identifier errors as you write, the same way it catches common SQL keyword typos.
Broken: double quotes around a value
SELECT * FROM users WHERE name = "John";-- ERROR: column "John" does not exist-- LINE 1: SELECT * FROM users WHERE name = "John";