§

Format SQL queries

Dialect
Indent
Keyword case
Linebreak before clause
§

Paste SQL

§

Formatted SQL

US data-engineering teams treat SQL formatting as a pull-request review gate. GitHub PR diffs against a Snowflake warehouse become unreadable when one engineer hand-formats a 200-line CTE and another pastes it back as a single line; the diff explodes into noise that hides the actual logic change. dbt Labs ships a SQL style guide that most US analytics-engineering startups adopt verbatim, and Snowflake Snowsight reformats queries on save with conventions that match the sql-formatter defaults this tool uses. Running queries through a consistent formatter before commit cuts review cycles and makes the column-order diff the reviewer actually needs to read sit on its own line.

How SQL formatting works

SQL formatting is a lexer-driven rewrite that walks every token in the query and re-emits whitespace around it based on the rules for the chosen dialect. The query semantics never change, only the layout.

  1. Pick a dialect. MySQL backticks, PostgreSQL :: casts, BigQuery dotted table paths, and T-SQL square-bracket identifiers each need a tokenizer that knows about them. The dialect selector chooses which grammar to apply.
  2. Tokenize the input. The formatter splits the query into a stream of tokens: keywords (SELECT, JOIN), identifiers, literals, operators, parentheses, and comments. String literals and quoted identifiers are passed through untouched so dialect-specific syntax keeps working.
  3. Apply layout rules. Top-level clauses (SELECT, FROM, WHERE, GROUP BY, ORDER BY) start on their own line. Comma-separated expressions in the select list and column lists each get a line, indented by the chosen indent unit.
  4. Apply keyword case. The keyword-case toggle rewrites recognised SQL keywords to uppercase, lowercase, or preserves the input casing verbatim. Identifiers are never touched — column and table names always come through as written.
  5. Emit the formatted string. The token stream is joined back into a single string with the indent character (2 spaces, 4 spaces, or tab) and the configured linebreak rule. Live mode re-runs the whole pipeline on a 200 ms debounce as you type.

Why pretty-print SQL

  • Pull-request diff readability. A 200-line CTE rewritten as one line turns a code review into a guessing game. Consistent formatting keeps the diff scoped to the change you actually made — a new column, an extra JOIN, a different WHERE predicate — so the reviewer can see it without untangling whitespace.
  • Easier debugging. When a query returns the wrong row count, the first thing you do is read it line by line. Formatted SQL puts each JOIN on its own line and lines up WHERE predicates so a missing AND or a stray OR shows up at a glance.
  • Consistent team style. Most teams adopt a SQL style guide (dbt Labs, GitLab, Mode Analytics all publish theirs) and want every committed query to follow it. A formatter run before commit removes the style argument from review and leaves only the logic to discuss.
  • Sharing SQL in docs. Runbooks, incident retros, and Notion docs all benefit from SQL that reads top-to-bottom. Formatted SQL pastes cleanly into a fenced code block and prints predictably in PDF exports, with no awkward line wraps mid-keyword.

Common applications

SQL formatting shows up across analytics engineering, backend development, and operations work whenever a query has to be read by someone who didn’t write it.

  • Analytics engineering: pre-commit hook in a dbt project that reformats every model file so PR diffs stay scoped to logic changes, not whitespace churn.
  • Database administration: paste a one-line slow-query log entry, format it, and walk through the join order while writing the incident retro.
  • Documentation: take a query out of a Looker explore or Tableau workbook, format it for a runbook, and embed it as a copy-pasteable example for the on-call rotation.

A worked example

Paste SELECT u.id,u.email,COUNT(o.id) FROM users u LEFT JOIN orders o ON o.user_id=u.id WHERE u.created_at > '2024-01-01' GROUP BY u.id,u.email ORDER BY u.id; into the input pane with dialect set to PostgreSQL, indent 2 spaces, and keyword case UPPER. The output places SELECT, FROM, LEFT JOIN, WHERE, GROUP BY, and ORDER BY on their own lines; each column in the select list and the group-by list gets its own indented line; and the ON predicate sits one indent deeper than the JOIN keyword it belongs to. The same query through the BigQuery dialect produces identical output for this case but would keep backtick-quoted identifiers if any were present.

FAQ

Which SQL dialects are supported?

The dialect dropdown covers Standard SQL, MySQL, PostgreSQL, SQLite, MariaDB, Transact-SQL (SQL Server / Azure SQL), BigQuery, Snowflake, and Redshift. The underlying sql-formatter library also recognises DuckDB, Spark SQL, Hive, Trino, Db2, N1QL, PL/SQL, ClickHouse, TiDB, and SingleStoreDB — picking the closest dialect produces sensible output even when the exact target isn’t in the list. Identifiers, string literals, and dialect-specific operators (PostgreSQL @>, BigQuery SAFE. prefixes) are preserved verbatim.

Does this validate my SQL?

No. The formatter is a lexical rewriter, not a parser. It tokenizes the input, applies layout rules, and emits the result; it does not check whether the query is semantically valid, whether the referenced tables exist, or whether the syntax is legal in the chosen dialect. Run the formatted output through the actual database (or a SQL linter such as SQLFluff) for a real correctness check.

Why are my keywords being uppercased?

The Keyword case dropdown defaults to UPPER, which is the convention in most published SQL style guides (dbt Labs, Mode, GitLab). Switch to lower if your team writes select / from in lowercase, or Preserve if you want the output to keep whatever casing you typed. Identifiers are never affected — only the recognised keyword set is rewritten.

Is my query uploaded anywhere?

No. The vendored sql-formatter library runs in your browser, the formatting happens locally on your machine, and the query text never crosses the network. The only outbound requests this page makes are the same shared analytics and ads requests every page on tools.ultim8soft.com makes; the SQL text itself is not part of either.

Pretty-printed SQL stops being a style argument once a formatter handles it. The tool runs entirely in your browser, the query never leaves the page, and the same dialect-aware tokenizer that powers the sql-formatter npm package does the rewrite.