SQL Formatter

[ FORMATTED SQL ]
SELECT u.name, COUNT(o.id)AS orders FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE u.active = TRUE AND u.note < > 'select one from the list' GROUP BY u.name ORDER BY 2 DESC
36 tokens · 1 statements
Tokens36
Statements1
This lays SQL out to be read. It does not parse, validate or rewrite it — a formatter that claimed to validate SQL would be claiming to implement a dialect.
Text inside quotes was left exactly as it is. A formatter that uppercases keywords with a plain search would turn a note reading "select one from the list" into SQL-looking nonsense — silently changing data inside a query you asked only to tidy.
Only keywords were recased. Identifiers are never touched: in PostgreSQL an unquoted identifier folds to lower case and a quoted one does not, so changing the case of one can change which column it refers to.
[ WHAT THIS IS ]

What is inside quotes is not code, and that is the whole difficulty. A formatter that uppercases keywords with a plain search turns a note reading 'select one from the list' into 'SELECT one FROM the list'silently changing data inside a query you asked only to tidy.

So it tokenises first, and only a keyword is ever recased. Comments are treated the same way.

Column names are not touched either. In PostgreSQL an unquoted identifier folds to lower case and a quoted one does not — so recasing one can change which column a query means.

And it does not parse or validate. It lays a statement out to be read. A formatter claiming to validate SQL would be claiming to implement a dialect.

[ QUESTIONS ]

Will it change text inside my quotes?

No, and that is the main thing this tool gets right. A formatter that uppercases keywords with a plain search turns a note reading “select one from the list” into SQL-looking nonsense — silently changing data inside a query you asked only to tidy. This tokenises first, so only something identified as a keyword is ever recased. Comments are left alone for the same reason.

Why does it not uppercase my column names?

Because case can be meaningful. In PostgreSQL an unquoted identifier folds to lower case while a quoted one does not, so "Order" and Order are different columns — recasing one can change which column a query means. Only keywords are touched.

Does it handle backticks and square brackets?

Yes. Double quotes are the standard identifier delimiter, backticks are MySQL and square brackets are SQL Server, and all three are kept exactly as written. That is what makes a column called order work, and getting it wrong is how a formatter mangles a perfectly valid query.

Does it check my SQL is valid?

No. It lays a statement out so a person can read it, which is what you need when staring at a 400-character line from an ORM. It does not parse, validate or rewrite — a formatter claiming to validate SQL would be claiming to implement a dialect, and there are several that disagree.

What happens to a broken query?

It gets formatted anyway. Somebody with a query that will not run still wants to see its shape, and refusing to lay it out removes the one thing that might show them where it went wrong.

Is my query sent anywhere?

No. Everything happens in your browser and nothing is transmitted or stored — which matters here, because a query often carries table names, column names and sometimes real values from your own database.

[ THE MATHS ]
What is changed and what is not
Keywordsrecased
Column namesuntouched
Text inside quotesuntouched
Commentsuntouched
[ THREE DIALECTS, THREE QUOTES ]
"order"the standard, PostgreSQL
`order`MySQL
[order]SQL Server

All three are kept as written. That is what makes a column called order work.

[ NEXT ]
43JSON FormatterFor the result set rather than the query
65XML & HTML FormatterThe same job, different language
55Text RedactorBefore pasting a query into a ticket
48Text ComparisonCheck two queries really are the same
[ IMPORTANT ]

Runs entirely in your browser; nothing is transmitted. This lays a query out to be read — it does not parse, validate or rewrite it. Only keywords are recased; identifiers and anything inside quotes are left exactly as written. Nothing you type here is sent to our servers — the calculation runs entirely in your browser.