SQL Formatter

Pretty-print and indent messy SQL: clause-per-line layout, aligned joins, and optional keyword uppercasing. String literals and comments are preserved. Runs in your browser.

Formatted

SELECT u.id, u.name, COUNT(o.id) AS orders
FROM users u
  LEFT JOIN orders o
  ON o.user_id = u.id
WHERE u.status = 'active'
  AND u.created_at > '2024-01-01'
GROUP BY u.id, u.name
HAVING COUNT(o.id) > 2
ORDER BY orders DESC
LIMIT 20;

String literals, quoted identifiers, and comments are preserved exactly — only whitespace and keyword case change, so the statement stays semantically identical.

About this tool

A one-line SQL query copied from a log or an ORM is hard to read and harder to review. This formatter parses the statement and lays it out the conventional way: each major clause (SELECT, FROM, WHERE, GROUP BY, ORDER BY, and so on) starts a new line at the base indent, joins and their ON conditions are grouped, AND/OR conditions are indented under WHERE, and keywords can be uppercased so they stand out from identifiers. Crucially, it works by tokenizing the SQL first — string literals, quoted identifiers, and both line and block comments are pulled out and put back untouched — so reformatting can never alter what the query means. The transformation only changes whitespace and keyword case; the exact tokens, in the exact order, are preserved. It runs entirely in your browser, so even queries containing sensitive table or column names never leave your machine. It is a readability formatter, not a linter or a full SQL parser, so it favors clean layout over dialect-specific validation.

How to use it

  • Paste a SQL statement (any dialect).
  • Toggle 'Uppercase keywords' to match your house style.
  • Read the formatted, clause-per-line output.
  • Copy it back into your editor or pull request.

Frequently asked questions

Will formatting change what my query does?
No. The formatter only adjusts whitespace and the case of recognized keywords. String literals, quoted identifiers, and comments are extracted before formatting and restored verbatim, so the sequence of tokens — and therefore the meaning — is identical to the input.
Does it work with my SQL dialect?
Largely, yes. It recognizes the standard clause keywords shared across PostgreSQL, MySQL, SQL Server, SQLite, and others, and it treats anything it does not recognize as an identifier, so dialect-specific functions and syntax pass through intact. It is a layout tool, not a dialect validator.
Why are my comments and strings left exactly as written?
Because changing them could change behavior or meaning. A string like '-- not a comment' must stay exactly that, and a real comment should keep its text. The tokenizer isolates them so the formatter never touches their contents.
Can it uppercase or lowercase keywords?
It can uppercase recognized keywords (the common convention that makes SELECT, FROM, and WHERE pop), controlled by a toggle. Turn it off to leave keyword case exactly as you typed it.
Does it validate my SQL?
No. It does not check that your query is syntactically or semantically correct — it just formats whatever you give it. Run the query against your database (or a linter) to validate it.
Is my SQL sent to a server?
No. Parsing and formatting happen entirely in your browser with no network request, so queries with confidential schema or data stay local.

Related tools