SQL Formatter
Reformat a SQL query: one clause per line, consistent keyword case, short lists kept inline. Never changes your query, and never claims your SQL is valid.
SQL Formatter
This reformats and does not validate. It will happily lay out select from where, because telling a broken query from an unusual one is a parser's job and this is not one. If you need to know whether your SQL is valid, run it against the database — which is the only thing that actually knows.
Paste a query, or pick an example above.
How to use this tool
A SQL formatter has one job and one hard requirement: make a query readable without changing what it says. The first part is a matter of taste and everyone has one. The second part is a property you can check, and it is the part that matters.
- 1Paste a query and press **Format**. Nothing is computed until you do.
- 2Change the layout options and the output re-formats immediately — they change how it looks, never what it contains.
- 3Use **Copy** or **Download .sql** to take the result away.
The query is not changed
This is the guarantee, and it is stated precisely: **whitespace and keyword case are the only things this tool alters.** Every identifier, every string literal, every number, every operator and every comment comes out exactly as it went in.
That is checkable, so it is checked. The test suite strips exactly what a formatter is allowed to change — whitespace, and the case of words that are SQL keywords — and nothing else, then asserts the result is identical for the input and the output. It runs over a corpus of fifty-one statements: subqueries, window functions, common table expressions, nested comments, dollar-quoted bodies, casts, quoted identifiers in all three styles, and a query with a syntax error in it.
Those expectations come from **sqlparse**, an independent SQL implementation in Python, rather than from a stored copy of this tool's own output. That distinction is the whole point: a test comparing a formatter to itself passes perfectly when the formatter is wrong.
What that caught
The check earned its place immediately, by finding a bug in the feature meant to improve the output. Folding a short list onto a single line joined the lines with a space, and a comment inside the list was glued to the code after it:
SELECT a, -- the first column b -- and the second
FROM tRead that again: the identifier `b` is now inside the comment, so the query genuinely says something different. The layout feature was the cause. Comments are now excluded from the folding, and there is a test for exactly this input.
Layout is an opinion, and formatters disagree
Here is the thing worth knowing before you compare this output with another tool's. **There is no standard for SQL formatting.** The major formatters do not produce the same output for the same query, and they are not all wrong.
The most common complaint about `sqlparse`, for example, is that it breaks a two-column `SELECT` list across two lines, and that it explodes `IN (1, 2, 3)` over three. Both are layout decisions rather than errors. This tool makes the opposite choice in both cases: a list that fits the line stays on it, and a value list never breaks. You can turn that off with **One item per line**, and you can widen the wrap column.
It does not validate, and it cannot
This reformats and nothing more. Paste `select from where` and it will lay it out neatly, because **telling a broken query from an unusual one is a parser's job**, and this is a formatter.
The distinction matters more than it sounds. A tool that refused to format invalid SQL would be a validator wearing a formatter's clothes, and it would be refusing a great deal of legitimate SQL in the process: vendor extensions, a dialect you have not declared, a query with a placeholder your client library fills in. If you need to know whether your SQL is valid, run it against the database. That is the only thing that actually knows.
The dialect it assumes, and why there is no switch
This reads a double-quoted run as a **quoted identifier**, which is the ANSI rule. MySQL reads it as a **string**. Backticks and SQL Server's square brackets are read as quoted identifiers too.
There is no dialect selector, and that is deliberate. Nothing in the text distinguishes the two cases — `"x"` is the same four characters either way — so a switch would have to be set correctly by the reader, who is the only person who knows which database they are writing for. A control that cannot be right by default is worse than an assumption that is named, so the assumption is in the status bar and here.
What the layout rules *are* dialect-neutral, incidentally: they are about commas, brackets and clause keywords, and those are the same everywhere. Only the tokeniser has an opinion, and it has one.
Why there is no library behind this
The obvious choice was `sql-formatter`, and it was measured rather than assumed: about 3 MB unpacked, two direct dependencies, and one of those pulls in four more — including a command-line argument parser, a fuzzing helper and a railroad-diagram renderer, none of which a web page can use.
Because this site has no server and loads one shared script bundle on every page, that would have been a cost paid by every visitor to every page of the site, in exchange for a tool whose entire output is whitespace. The argument for a dependency is much weaker here than it is for a YAML parser: a YAML parser has to resolve tags and anchors, and getting that wrong destroys data, whereas a formatter that gets it wrong produces something ugly and obviously wrong.
The trade is real and worth naming. Hand-rolling means the keyword list is this project's, and it will not cover every vendor's reserved words. Where a word is genuinely reserved and this tool does not know it, the only consequence is that it stays lowercase — the query is unchanged either way.
The cases worth knowing about
- **Block comments nest.** PostgreSQL treats `/* a /* b */ c */` as one comment, and so does this. Some tools stop at the first `*/` and turn the rest of your file into a comment, which is a silent truncation rather than an error.
- **Dollar-quoted bodies are opaque.** `$$a; select b;$$` is one string, so the semicolon and the `select` inside it do not end the statement. A formatter that splits there will mangle a function body.
- **A doubled quote is an escaped quote.** `'it''s'` is one string, and a tokeniser that ends it at the first quote will reformat the remainder of the line as SQL.
- **An unrecognised character is passed through, not dropped.** A dialect this has never seen produces ugly output rather than a query that quietly changed.
The last one is the important one, and it is why the page can promise the query is unchanged. The alternative — skipping a character it does not recognise — would be faster to write and would be the one bug that matters.
Frequently asked questions
- Will this change my query?
- No. Whitespace and keyword case are the only things it alters, and that is enforced by a test rather than promised by the page. The suite strips exactly those two things and asserts the result is identical before and after, across fifty-one statements checked against an independent implementation.
- Why does my SQL formatter output look different from this one?
- Because there is no standard for SQL layout and the major formatters genuinely disagree. This one keeps a short list on one line and never breaks a value list, because those are the most common complaints about the alternatives. That is a choice, not a correctness question, and you can change it with the layout options.
- Does it tell me if my query is wrong?
- No, and it cannot. Telling a broken query from an unusual one requires a parser, and this is a formatter — it will lay out `select from where` perfectly happily. Run your SQL against the database to find out whether it works.
- Which SQL dialect does this use?
- ANSI, and specifically it reads a double-quoted run as a quoted identifier. MySQL reads the same characters as a string. There is no dialect switch, because nothing in the text distinguishes the two and only you know which you are writing. The layout rules are dialect-neutral; only the tokeniser has an opinion.
- Why did you not use the sql-formatter library?
- It was measured: about 3 MB unpacked with six transitive packages including a CLI argument parser, none of which a browser can use, and this site would have paid for it on every page. Since every panel's code shares one bundle here, that is a site-wide cost for a tool whose entire output is whitespace. A YAML parser earns its dependency; a formatter does not.
- Is my query uploaded anywhere?
- No. The formatting runs in this browser tab, and there is no server component to this site for it to go to.