SQL Formatter

Beautify SQL for MySQL, PostgreSQL, SQL Server and more.

Runs locallyYour input is processed in this tab. The editor blocks outgoing network requests.
SQL input

The SQL Formatter turns one-line or inconsistently indented queries into readable, reviewable SQL. It beautifies SELECT, INSERT, UPDATE, DDL and CTEs for thirteen dialects, including MySQL, PostgreSQL, SQL Server, Oracle, BigQuery and Snowflake. It is built for developers and analysts who paste internal queries. Everything runs in your browser — nothing is uploaded.

How to format SQL

  1. Paste a query, drop a .sql file, or choose Load example. Several statements separated by semicolons are formatted together.
  2. Pick your database in the Dialect menu in the title bar. It changes how identifiers, placeholders and dialect-only keywords are read, so it matters more than any other option.
  3. Copy the result with ⌥/Alt C, download it with ⌘/Ctrl S, or use a Next action to switch keyword case, move to leading commas, or minify the query to one line.

Examples by dialect

Standard SQL: one-line query from a log

A query copied from an application log or ORM debug output, formatted with the defaults.

SQL
select o.id, o.total, c.name as customer from orders o join customers c on c.id = o.customer_id where o.created_at >= '2026-01-01' and o.status in ('paid','shipped') order by o.total desc limit 50;

Result:

SQL
SELECT
  o.id,
  o.total,
  c.name AS customer
FROM
  orders o
  JOIN customers c ON c.id = o.customer_id
WHERE
  o.created_at >= '2026-01-01'
  AND o.status IN ('paid', 'shipped')
ORDER BY
  o.total DESC
LIMIT
  50;

PostgreSQL: two statements with $1 parameters

With the PostgreSQL dialect, positional parameters, RETURNING and interval literals are recognized. Statements are separated by one blank line.

SQL
update users set last_seen = now() where id = $1 returning id;
delete from sessions where user_id = $1 and expires_at < now() - interval '30 days';

Result:

SQL
UPDATE users
SET
  last_seen = now()
WHERE
  id = $1
RETURNING
  id;

DELETE FROM sessions
WHERE
  user_id = $1
  AND expires_at < now() - INTERVAL '30 days';

SQL Server: TOP and bracketed identifiers

In Standard SQL this input stops at [Name]. With the SQL Server dialect, brackets are read as quoted identifiers.

SQL
select top 10 [Name],[Email] from dbo.[Users] where IsActive=1 order by CreatedAt desc

Result:

SQL
SELECT
  TOP 10 [Name],
  [Email]
FROM
  dbo.[Users]
WHERE
  IsActive = 1
ORDER BY
  CreatedAt DESC

MySQL: lowercase keywords and leading commas

Backtick identifiers with Keyword case set to lower and Comma position set to Leading.

SQL
select `user_id`, count(*) as orders from `shop`.`orders` where status = 'paid' group by `user_id` having count(*) > 3;

Result:

SQL
select
  `user_id`
  , count(*) as orders
from
  `shop`.`orders`
where
  status = 'paid'
group by
  `user_id`
having
  count(*) > 3;

Options explained

  • Dialect — selects the grammar used to tokenize the query: Standard SQL, MySQL, MariaDB, PostgreSQL, SQL Server, Oracle PL/SQL, SQLite, BigQuery, Snowflake, Spark, Redshift, Trino or DB2.
  • Keyword case — rewrites reserved words and data types in UPPER or lower case, or keeps them exactly as written with Preserve.
  • Indent — sets each nesting level to 2 spaces, 4 spaces or a tab.
  • Lines between queries — inserts one or two blank lines between statements that end in a semicolon.
  • Comma position — places list commas at the end of each line (Trailing) or at the start of the next line (Leading).

Troubleshooting SQL formatting

"Couldn't parse near [Name]" or near a backtick

The current dialect does not recognize that quoting style. Brackets belong to SQL Server, and backticks to MySQL, MariaDB, BigQuery and Spark. When the input contains dialect-specific syntax, a notice such as "Looks like SQL Server" suggests the dialect to switch to.

Placeholders such as $1, :name or @p are rejected

Standard SQL, PostgreSQL and Redshift accept all four common styles — ?, $1, :name and @p — so queries written for most drivers format there. Other dialects accept only their own: MySQL, for example, stops at :name, and SQL Server at $1. Switch to Standard SQL, or to the dialect your driver targets.

A misspelled keyword is formatted as text

A typo such as form is valid SQL to the tokenizer — it becomes an alias — so the query still formats, but badly. The notice "Did you mean FROM?" marks the line; correct it and the layout snaps into place.

"A string literal is not closed"

An odd number of single quotes leaves the rest of the query inside a string. Escape an apostrophe by doubling it, as in 'O''Brien'.

The parser stops at the end of the query

An unbalanced parenthesis, often in a subquery, usually causes this. Count the brackets, or use Format anyway, the best-effort tokenizer that indents by keyword without requiring valid syntax.

A column name became uppercase

Names that are also keywords — month, year, date — are cased like keywords. Set Keyword case to Preserve, or quote the identifier, to keep it as written.

FAQ

Does the formatter change what my query does?

No. It changes only whitespace, line breaks, the case of keywords and, with the leading option, where commas sit. Identifiers, string literals, numbers, comments and placeholders are passed through as written. If the parser cannot understand part of the query, it reports an error instead of guessing, and the best-effort mode only rearranges whitespace and keyword case.

Is it safe to paste production queries here?

Yes. The formatter runs in your browser, and the editor sits in an isolated frame that blocks network requests, so the query is never uploaded or stored on a server. Your dialect, indent and keyword-case settings are remembered on this device; the query itself is kept only if you turn on "Remember my last input".

Which dialect should I pick if my database is not listed?

Pick the closest relative. MariaDB and most MySQL-compatible services use MySQL, Aurora PostgreSQL uses PostgreSQL, and Azure SQL uses SQL Server. Standard SQL rejects vendor quoting such as brackets and backticks, but accepts the common placeholder styles; if you see a parse error there, a vendor dialect usually fixes it.

Can I format several statements at once?

Yes. Paste them separated by semicolons and each statement is formatted in turn, with one or two blank lines between them depending on Lines between queries. The status bar shows how many statements were found. Stored procedure bodies with custom delimiters are harder to split, so format those one block at a time.

How do I pretty print SQL into a single line instead?

Use the Minify mode, or the Minify Next action, to collapse the query onto one line while keeping strings and identifiers intact. The dedicated SQL Minifier adds an option to keep comments as /* */ blocks, which is useful when a query must live in a config file or log line.

Are comments kept when I beautify SQL?

Yes. Both -- line comments and /* */ block comments are preserved and placed next to the code they describe. Because they are comments, their contents are never re-cased or re-indented internally, so aligned notes and commented-out code inside a block comment stay exactly as you wrote them.

SQL formatting conventions we follow

The formatter uses the open-source sql-formatter engine with a small set of fixed rules, so the same query always produces the same layout.

  • Each clause starts a line. SELECT, FROM, WHERE, GROUP BY, ORDER BY and LIMIT sit at the left edge, and their contents are indented one level below.
  • One column per line. Select lists and GROUP BY lists break after every item, which keeps diffs to one line when a column is added.
  • Joins stay with FROM. JOIN … ON … is indented under FROM so the full data source reads as one block.
  • Boolean operators lead. AND and OR begin their lines, so each condition can be commented out or reordered on its own.
  • Function names are left alone. Keyword case applies to reserved words and data types such as VARCHAR; now(), sum() and date_trunc() keep the case you typed.
  • Comments and literals are preserved. Strings, quoted identifiers and -- or /* */ comments come through unchanged.

For the reasoning behind these choices, and where teams reasonably differ, read the SQL formatting conventions guide.

When you are done, compress the query to one line, format a JSON result set returned by an API, or turn an exported CSV into records with CSV to JSON. Every SQL tool is listed on the SQL category page.

Browse all SQL Formatters

Guides