How to use the SQL formatter
- Paste one query or a whole script — several statements separated by semicolons are fine. It is formatted as you paste.
- Pick your database under Dialect, so that its quoting rules are understood (see the table below), and choose how keywords are written: UPPERCASE, lowercase or as written.
- Choose Format for one clause per line with 2 spaces, 4 spaces or a tab, or One line to squeeze each statement onto a single line for a log, a config file or a code string.
- Press Copy beside the result, or Download to save it as a .sql file.
How the query is laid out
The formatter reads your SQL as tokens — keywords, names, strings, numbers, operators, comments — and lays them out with a few fixed rules:
- Main clauses start a line:
SELECT,FROM,WHERE,GROUP BY,HAVING,ORDER BY,SET,VALUESandRETURNINGget a line of their own with their content indented below;LIMIT,UNION,INSERT INTO,UPDATE,DELETE FROM,WITHandCREATE TABLEkeep their content on the same line. - Lists go one item per line: the columns of a
SELECT, the rows ofVALUES, the assignments ofSET, the columns ofCREATE TABLEand the common table expressions ofWITH. Commas inside function calls andIN (…)lists stay on the line. - Joins sit under
FROM, withONon the same line; eachANDorORof aWHERE,HAVINGor join condition starts a new line — except theANDofBETWEEN … AND …. - Subqueries are nested: a parenthesis that opens a
SELECTis indented one more level and closed on its own line.CASEputs eachWHENandELSEon a line and lines upENDwithCASE. - Statements are separated by a blank line.
What is never changed
Strings, quoted names ("Order", `order`, [Order Date]), numbers, comments and PostgreSQL dollar-quoted bodies are copied exactly as written. Keyword case changes only for SQL keywords and, right before a parenthesis, for built-in function names such as COUNT( or COALESCE(. Names of your tables and columns keep their spelling, and so do words that are keywords in some databases but common column names — date, name, status, type, value, timestamp. A name after a dot, as in t.order, is always treated as a name. Nothing is added or removed except whitespace, so the formatted query returns the same result.
Worked example
The sample in the box is a one-line report query with a comment, a CASE expression, a join condition with two parts, an IN list and a HAVING clause. Formatted with the defaults:
-- top customers this year
SELECT
c.id,
c.name,
COUNT(o.id) AS orders,
SUM(o.total) AS spent,
CASE
WHEN SUM(o.total) > 1000 THEN 'gold'
ELSE 'standard'
END AS tier
FROM
customers c
LEFT JOIN orders o ON o.customer_id = c.id
AND o.status <> 'cancelled'
WHERE
o.created_at >= '2026-01-01'
AND c.country IN ('US', 'CA')
GROUP BY
c.id,
c.name
HAVING
COUNT(o.id) > 2
ORDER BY
spent DESC
LIMIT 10;
The comment stays on its own line, the strings keep their quotes, and the identifiers c, o and spent keep their case. A subquery and a common table expression look like this:
WITH recent AS (
SELECT
customer_id
FROM
orders
WHERE
created_at > NOW() - INTERVAL '30 days'
)
SELECT
name
FROM
customers
WHERE
id IN (
SELECT
customer_id
FROM
recent
)
Dialects: what the choice changes
SQL is written slightly differently in each database, mostly in how text is quoted. The dialect tells the formatter how to read the text — it never rewrites your SQL for another database.
| Dialect | Read differently |
|---|---|
| Standard SQL | 'text' with '' for a quote inside, "name", -- comment and /* comment */ |
| MySQL / MariaDB | "text" is a string, a backslash escapes ('It\'s'), `name`, # comment; -- starts a comment only when a space follows |
| PostgreSQL | $$ … $$ and $tag$ … $tag$ bodies kept whole, E'…' strings with backslash escapes, nested /* /* */ */ comments, :: casts, $1 parameters |
| SQL Server (T-SQL) | [name] with ]] inside, N'text', @variables, #temp tables, nested comments, and GO on its own line as a batch separator |
| Oracle (PL/SQL) | q'[It's]' alternative quoting, :bind variables |
| SQLite | [name] and `name` as well as "name"; ?, ?1, :name, @name and $name parameters |
The difference matters: 'It\'s' is a complete string in MySQL, but in standard SQL the backslash is an ordinary character, the string ends at the second quote and the third one opens a string that never closes. With the wrong dialect you may see “String not closed”.
Errors it reports
The formatter is not a full SQL parser and doesn’t check that a query is valid for your database. It stops only where it can’t know where a token ends: a string, quoted name, comment or dollar-quoted body that isn’t closed, a parenthesis without its partner, and curly quotes (‘ ’ “ ”) pasted from a word processor or a chat. Each one shows the line, the column and the spot marked with ^.
Limits and tips
- Procedural code — PL/pgSQL, T-SQL
BEGIN … ENDblocks, PL/SQL packages — is laid out like plain statements; a PostgreSQL function body in$$is kept exactly as written. - Long lists inside
IN (…)and long function calls stay on one line. - One line keeps
--comments, so a line break follows each one; everything else of a statement is on one line. - To compare two versions of a query, format both the same way and paste them into the diff checker. Query results in JSON or XML can be tidied with the JSON formatter and the XML formatter.
Your SQL stays on your device
Formatting runs in your browser. Queries often reveal table names, customer data in literals and the structure of your database; none of it is uploaded or logged, and it isn’t saved either: reloading the page clears it.
Frequently asked questions
Does formatting change what my query does?
No. Only whitespace and the case of keywords change, and SQL keywords are case-insensitive. Strings, quoted names, numbers and comments are copied exactly, so the query returns the same rows.
Which dialect should I choose?
The database the query runs on. The choice only changes how quotes, backslashes and comments are read; if your query uses none of the special forms in the table above, every dialect gives the same result.
Why wasn’t a word like date or name uppercased?
Words such as date, name, status, type, value and timestamp are keywords in some databases but very common column names, so they keep the spelling you wrote. Function names like count or date are uppercased only when a parenthesis follows them.
Can it fix syntax errors in my SQL?
It finds strings, comments and quoted names that aren’t closed, unbalanced parentheses and curly quotes, and shows where they are. Other mistakes, such as a misspelled keyword or a missing comma, are formatted as they are — your database reports those.
Is my SQL uploaded?
No. The formatter runs as JavaScript in your browser, so your queries never leave your device, and it keeps working offline once the page has loaded.
Last updated: October 16, 2026