99tools

SQL Formatter

runs in your browser

Pretty print or minify SQL for PostgreSQL, MySQL, SQL Server, SQLite, Oracle and more, and fill ?, $1 and :name parameters back into a logged query.

Output
Keywords
Indent

Text inside quotes, quoted identifiers and dollar-quoted bodies is never rewritten.

SQL

Formatted

about this tool

Making a query readable

Paste SQL that arrived as one long line — out of a log, an ORM's debug output, a migration file — and get it back indented, with clauses on their own lines and joins lined up. Minify does the reverse when you need the query back on one line for a config value or a log message.

If the one long line is JSON or XML rather than SQL, the JSON formatter and XML formatter do the equivalent job.

Dialects

The formatter understands the syntax differences between PostgreSQL, MySQL, SQLite, T-SQL, PL/SQL, BigQuery, Snowflake and Spark, plus standard SQL.

Picking the right one matters because dialects disagree about the things a formatter has to parse: how identifiers are quoted (double quotes, backticks or square brackets), how strings are escaped, and what counts as a keyword. PostgreSQL's dollar-quoted function bodies are the clearest example — a formatter that does not know about $$ will mangle the contents of a stored procedure.

Keyword case

Upper, lower or preserve. Uppercase keywords against lowercase identifiers is the long-standing convention, and it earns its keep: it makes the structure of a query scannable, because SELECT, FROM and WHERE stand out from your table and column names. Preserve is there for codebases with a house style, or a linter, that says otherwise.

Putting the values back in

A logged query is rarely runnable. The driver logs where status = $1 and placed_at >= $2 and the values end up on another line, or in another field, or in a different log entirely. Tick fill in parameters and every placeholder in the statement gets a box: ?, ?3, $1, :name and @name are all recognised, wherever the driver you use puts them.

Values are written the way the dialect you picked writes literals. An apostrophe in a name is doubled so the value stays one string; a backslash is doubled as well for MySQL and Spark, where it is an escape character and not a plain character. null, true and false are read as themselves, numbers stay numbers, and everything else is quoted — except that a number with a leading zero is quoted too, because 007 is almost always a code rather than seven.

Each parameter can be pinned to a kind if the guess is wrong: text, number, null, or raw SQL for the case that needs it, such as a list inside in (…). Raw is put in exactly as typed and is the one kind that is not escaped, which the page says next to the result. A parameter left empty stays as it was written, so a half-filled statement still shows what it is waiting for.

This is for reading a query, not for building one. Putting values into SQL as text is precisely what parameters exist to prevent. A driver sends the statement and the values separately, so a value can never become part of the statement; anything produced here is a single piece of text where that separation has been thrown away. Use it to reproduce a query from a slow query log, and keep the parameters in the code.

Placeholders are found in code only. A ? inside a string, a :name in a comment, a ::text cast and a @@version are all left alone.

What is left alone

Comments, string literals and quoted identifiers pass through untouched. That sounds obvious and is the hard part of writing a SQL formatter: a semicolon inside a string is not a statement boundary, and a -- inside a quoted identifier does not start a comment. Content inside those is scanned separately so it is never reformatted or split.

This formats; it does not check

The output is a reformatted version of what you pasted, not a validated query. It will not tell you that a column does not exist, that a join is missing a condition, or that the query will be slow. It also does not rewrite your SQL — formatting only ever changes whitespace and keyword case, never the meaning.

If a query is slow, the tool you want is your database's own EXPLAIN, which knows about your indexes and your data.

Safe to paste

Formatting and filling in parameters both happen in the page. Queries routinely contain table names, business logic and literal values from production, so nothing is transmitted.

questions

Does choosing the right SQL dialect matter?
Yes, because dialects disagree about exactly what a formatter must parse: how identifiers are quoted, how strings escape, and which words are keywords. PostgreSQL's dollar-quoted function bodies are the clearest case — a formatter unaware of $$ will mangle a stored procedure.
Should SQL keywords be uppercase?
It is the long-standing convention and it earns its keep: uppercase keywords against lowercase identifiers make a query's structure scannable at a glance. Preserve mode exists for codebases whose house style or linter says otherwise.
Will it change what my query does?
No. Formatting only alters whitespace and keyword case. Comments, string literals and quoted identifiers are passed through untouched, which is the difficult part of writing a SQL formatter, since a semicolon inside a string is not a statement boundary.
Can it tell me why my query is slow?
No, it only reformats. It will not know your indexes, your data volume or your query plan. Use your database's own EXPLAIN for that.
Can it put the values back into a logged query?
Yes. Tick fill in parameters and every ?, $1, :name or @name in the statement gets a box. Values are quoted for the dialect you picked, so a value containing an apostrophe stays one string. It is for reading a logged query back, not for building queries: a driver sends values separately, and that is what stops a value from turning into SQL.
Why does my query fail to format with :name in it?
Because standard SQL has no such placeholder, so the parser stops at it. Choose the dialect the query was written for, or fill the parameters in and format the result. The tool points at the placeholder rather than leaving you with an unexplained parse error.
Is my SQL sent to a server?
No, formatting happens in the page. Queries routinely contain table names, business logic and literal values from production.