SQL Formatter

Global tools

Paste a query and this tool lays it out the way a human reads SQL: one clause per line, indentation by depth, and the words it recognizes as keywords spelled in the case you choose. It is the smallest tool in the developer family for an honest reason - its formatting never refuses anything, because it never pretends to understand the grammar. It tokenizes quoted strings, quoted identifiers and comments so they are never touched, and copies everything it does not recognize character for character.

Paste one query or several - statements separated by `;`. Nothing is truncated.

How recognized keywords are spelled. Quoted identifiers are never touched.

Leave it blank for "query.sql".

Results update as you type. Nothing leaves your device.

Formatted SQL

9 lines

The query was split into one statement at top-level semicolons, laid out one clause per line and indented by depth. Only words this formatter recognizes were recased; every quoted identifier and string literal was copied verbatim.

Statements
1
Lines
9
Bytes
167 B
Words recased
13

SQL

SELECT u.id, u.email, COUNT(o.id) AS orders
FROM users u
JOIN orders o
ON o.user_id = u.id
WHERE u.active = true
GROUP BY u.id, u.email
ORDER BY orders DESC
LIMIT 10;

Copy it, or download it. The query says exactly what it said: nothing was reordered and nothing was dropped.

What the numbers do not say

  • Only keywords in the recognized list are recased; quoted identifiers and string literals are copied verbatim, so a column named "SELECT" stays "SELECT".
  • Parentheses keep the line they started on - a function call is never split in half - and a statement stays whole unless it ends with `;`.
  • Anything this formatter does not recognize is copied character for character: a dialect extension or an operator that is not in the list still survives untouched.
Nothing was sent anywhere, and the input was not modified - it was only read and rewritten.

What makes it a page rather than a build step is the honesty printed beside the result. Only recognized keywords are recased, parentheses stay on the line they started on, statements are split only at top-level semicolons, and nothing is ever reordered or dropped. A function call is never split in half, a column named "SELECT" stays "SELECT", and a dialect extension this formatter has never seen survives untouched - all of it stated, rather than left to be discovered in review.

About this sql formatter

A formatter for real databases parses the grammar, because knowing whether a word is a keyword or a column changes where a line may break. This one takes a deliberately lighter path: it tokenizes the things that must never be touched - quoted strings, quoted identifiers and comments - then recases the words it recognizes, breaks a line before the clauses that always start one (SELECT, FROM, WHERE and the rest), and indents by parentheses depth. That is a smaller promise than a full SQL formatter makes, and the page says so every time rather than implying it understands your dialect.

The result is a layout you can trust for one specific reason: the formatter never reorganizes anything it cannot see. Parentheses stay on their line, so `IN (1, 2, 3)` and `left(name, 3)` come out exactly as written; a `;` inside a function call does not end a statement; and unrecognized tokens are copied character for character. Everything runs in the tab, nothing is uploaded, and the static page already carries a formatted query from the sample so it is useful before anyone has typed.

How this sql formatter works

The things that are never touched

Quoted strings, quoted identifiers and comments are tokenised before anything else looks at them, and every one of them is copied verbatim. An identifier written `"SELECT"` is a column name, not a keyword, so it is never recased. A string literal such as `'WHERE x = 1'` is data, not a clause. The consequence is that a query with unusual spelling keeps exactly that spelling in the parts that mean it literally.

The recognized keyword list is fixed and modest - the clauses, the join words, the operators (AND, OR, IN, LIKE, IS NULL and similar). Anything outside that list is copied character for character: a dialect extension, a custom operator, a column that happens to look like a word.

Clause per line, indented by depth

After tokenising, the formatter breaks a line before the clauses that always start one - SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, OFFSET, UNION, VALUES, SET, RETURNING - and before JOIN and ON when they really introduce a join. The result is the shape a human reads: the query listed, one clause per line, no guesses about where an expression should wrap.

Indentation follows parentheses. A function call such as `count(o.id)` glues to its name and does not indent, while a grouping such as `IN (a, b, c)` is laid out with the list indented below the opening parenthesis. Parentheses themselves are never moved: a function call is never split in half.

Keyword case, as a choice

The keywords in the recognized list are spelled in the case you choose - upper (SELECT, FROM, WHERE) or lower (select, from, where). The page counts how many words that setting actually moved, comparing the two passes word by word, so the number beside the result is the real effect of your choice rather than a guess.

Quoted identifiers and string literals are never recased. So a column named "SELECT" stays "SELECT" even in lower mode, and a string literal keeps whatever case the data needs.

The honest limits, printed with every result

The formatter does not validate SQL and does not claim to. It lays out whichever tokens it can recognize and copies the rest verbatim, so a query that would not run still gets a tidy layout - a formatter is a layout tool, and the page never pretends otherwise.

Statements are split only at top-level semicolons, so several queries pasted together are handled one after another and counted. Nothing is reordered and nothing is dropped: the formatted text says exactly what the input said, with the bytes rearranged and the words that needed it recased.

Worked examples

Each example below was run through the calculator on this page when the site was built, so the numbers match what you see when you enter the same inputs.

A query, laid out one clause per line

Paste your query: select u.id, u.email, count(o.id) as orders from users u join orders o on o.user_id = u.id where u.active = true group by u.id, u.email order by orders desc limit 10;

Formatted SQL

9 lines

The query was split into one statement at top-level semicolons, laid out one clause per line and indented by depth. Only words this formatter recognizes were recased; every quoted identifier and string literal was copied verbatim.

Statements: 1 · Lines: 9 · Bytes: 167 B · Words recased: 13

Each clause starts its own line and the recognized keywords are uppercased.

Lower case, if that is the house style

Paste your query: SELECT id, name FROM users WHERE active = true ORDER BY name; · Keyword case: Lower - select, from, where

Formatted SQL

5 lines

The query was split into one statement at top-level semicolons, laid out one clause per line and indented by depth. Only words this formatter recognizes were recased; every quoted identifier and string literal was copied verbatim.

Statements: 1 · Lines: 5 · Bytes: 62 B · Words recased: 5

The same layout, with the recognized keywords spelled lower.

Several statements, counted

Paste your query: insert into log (msg) values ('hi'); select count(*) from log;

Formatted SQL

5 lines

The query was split into 2 statements at top-level semicolons, laid out one clause per line and indented by depth. Only words this formatter recognizes were recased; every quoted identifier and string literal was copied verbatim.

Statements: 2 · Lines: 5 · Bytes: 62 B · Words recased: 6

Each top-level `;` ends one statement, so the results panel counts both.

Frequently asked questions

Is my query uploaded anywhere?

No. The layout happens in JavaScript in this tab, the results panel is built from what is already on the page, and the download is a blob created locally. A query often contains data, schema detail or credentials, so nothing here touches a server at all.

Why are parentheses not reflowed?

Because inside parentheses a formatter that does not read the statement's structure has to guess whether the comma ends an argument or a list item, and how far to indent. This one never guesses: `IN (1, 2, 3)` and `left(name, 3)` come out exactly as written, with the list indented below the opening parenthesis where there is room. Layout you understand beats layout a tool invented for you.

Does it validate my SQL?

No, and it does not claim to. It recognizes the parts that must never be touched, recases the words it recognizes, and copies the rest verbatim - so a query that would not run still gets a tidy layout. Validation needs a full reader for your dialect; a formatter is a layout tool, and this page says so.

Will it recase a column named "SELECT"?

No. Quoted identifiers are tokenised before anything else and copied verbatim, so a column written `"SELECT"` keeps that spelling in both directions, and a string literal keeps its case too. Only words in the recognized keyword list, unquoted, are ever recased.

Can I change the keyword case after formatting?

Yes, and the count updates with it. The layout is identical whichever case you ask for - only the spelling of the recognized words moves - so you can compare the two passes and see exactly which words the setting changed.

Assumptions and sources

  • The formatter recognizes standard SQL keywords (SELECT, FROM, WHERE, JOIN and the rest) and leaves everything it does not recognize exactly as written.
  • Quoted strings, quoted names and comments are never altered, and a `;` inside a string or a function call does not end a statement.
  • Nothing is validated or reordered, and nothing leaves your browser: the SQL is only laid out.

Last reviewed 2026-10-07. Runs locally on your device; keep backups; no financial advice applies. Read the full disclaimer.

Where a figure on this page comes from an official agency — HUD, IRS, FICO or a state body — the site keeps a dated snapshot of the source page in its sources library, and a scheduled job re-checks that snapshot, so the number can be traced back to the document it came from.