NV ToolkitFormat · Validate · Convert

Formatters

SQL Formatter

Turn one-line query soup into clause-aligned, review-ready SQL — dialect-aware for MySQL, Postgres, T-SQL and SQLite.

In short

Format SQL online for MySQL, PostgreSQL, T-SQL and SQLite: clause-aligned layout, UPPERCASE keywords, and your indent style — instantly, in your browser.

By NaveenKumar T · Updated

Learn: How to Escape a Single Quote in SQL

  • Industry-standard formatting
  • Exact error line & column
  • 2/3/4-space or tab indent

Runs entirely in your browser — nothing you paste or open here is uploaded, logged, or stored.How we handle data →

Example

SQL Formatter: input and output

A customer-retention query as an ORM logged it: a CTE, a `::date` cast, a `FILTER (WHERE …)` aggregate, a window function and an `ILIKE` filter — run with the PostgreSQL dialect selected.

Input · sql
with recent as (select customer_id, max(created_at)::date as last_order from orders where created_at >= now() - interval '90 days' group by customer_id)
select c.id, c.email, r.last_order, count(o.id) filter (where o.status='refunded') as refunds, row_number() over (partition by c.region order by r.last_order desc) as rn from customers c join recent r on r.customer_id=c.id left join orders o on o.customer_id=c.id where c.email ilike '%@example.com' and c.region in ('eu','uk') group by c.id, c.email, r.last_order, c.region having count(o.id)>1 order by rn limit 50;
Output · sql
WITH
  recent AS (
    SELECT
      customer_id,
      MAX(created_at)::date AS last_order
    FROM
      orders
    WHERE
      created_at >= NOW() - interval '90 days'
    GROUP BY
      customer_id
  )
SELECT
  c.id,
  c.email,
  r.last_order,
  COUNT(o.id) FILTER (
    WHERE
      o.status = 'refunded'
  ) AS refunds,
  ROW_NUMBER() OVER (
    PARTITION BY
      c.region
    ORDER BY
      r.last_order DESC
  ) AS rn
FROM
  customers c
  JOIN recent r ON r.customer_id = c.id
  LEFT JOIN orders o ON o.customer_id = c.id
WHERE
  c.email ILIKE '%@example.com'
  AND c.region IN ('eu', 'uk')
GROUP BY
  c.id,
  c.email,
  r.last_order,
  c.region
HAVING
  COUNT(o.id) > 1
ORDER BY
  rn
LIMIT
  50;

With PostgreSQL selected the `::date` cast, `FILTER (WHERE …)` and `ILIKE` all parse; keywords and built-in functions are uppercased while identifiers and string literals are left exactly as written.

Learn more

Formatting SQL, properly

This page runs sql-formatter, the standard open-source SQL pretty-printer, with dialect grammars for standard SQL, MySQL, PostgreSQL, T-SQL and SQLite. Clauses land on their own lines, JOINs and subqueries indent by nesting depth, and keywords can be normalized to UPPERCASE — the layout conventions every SQL style guide converges on.

The classic moment is a query extracted from logs, an ORM's generated SQL, or a 400-character one-liner from a dashboard — paste it, pick the dialect, and read the actual query structure: which tables join where, what the WHERE really filters, where that mystery subquery begins and ends.

Help

Frequently asked questions

Everything you need to know about the SQL Formatter.

01How do I format SQL code here?

Paste your SQL, pick a dialect (Standard, MySQL, PostgreSQL, T-SQL or SQLite), and press Format. sql-formatter lays out clauses on their own lines, indents JOINs and subqueries by nesting depth, and can uppercase keywords — the dialect only matters for syntax specific to that database.

02Does the dialect choice actually matter?

For most queries, any dialect formats fine. It matters at the edges: PostgreSQL's :: casts and $1 parameters, MySQL's @variables and # comments, T-SQL's square-bracket identifiers. If your query uses dialect-specific syntax and formatting fails, switching the dialect selector usually fixes it — the error message points at the offending token.

03Which words get uppercased, and what does each dialect actually add?

With UPPERCASE on, sql-formatter capitalizes reserved keywords and the built-in functions of the selected dialect — `count` becomes `COUNT`, `row_number` becomes `ROW_NUMBER` — while identifiers, aliases and string literals are never touched. The dialect decides what counts as a keyword: under Standard, `TOP` and `ILIKE` are treated as identifiers and left lowercase, and `[bracketed]` names, `@variables`, `#` comments, `$1` parameters and `::` casts are parse errors. Choose T-SQL, MySQL or PostgreSQL respectively and they parse — MySQL also lays out `ON DUPLICATE KEY UPDATE` correctly.

Keep working

Related tools

Learn the format

Related guides

All guides →