My Tool Studio
Developer Tools·4 min read

How to Format SQL Queries for Review and Debugging

A query that came out of an ORM log or a BI export is technically correct and practically unreadable: one line, no breaks, aliases everywhere. Knowing how to format SQL queries turns that string back into something a colleague can review and you can debug. This guide walks through the SQL Formatter, its twelve dialect options, a worked before-and-after example with a JOIN, and the formatting habits that help long queries survive code review. The tool runs in your browser, so production schema names never leave your machine.

{"name": "site","tags": ["fast","clean"],"active": true}Beautified

Where unreadable SQL comes from

The scenario.

ORMs log queries as single lines because machines don't need line breaks. Slow-query logs, BI export screens, and APM traces all do the same. So the day a report runs slow, what you copy out of the log is a 700-character string with every clause jammed together and aliases like t3 scattered through it.

The other source is people. A teammate pastes a query into a pull request or a Slack thread exactly as it ran, and now three reviewers are scrolling sideways through a line that never ends. Formatting is the five-second fix in both cases.

How to format SQL queries with the dialect dropdown

Paste the statement into the SQL Formatter and look at the small dropdown in the top right. It defaults to postgresql and offers twelve grammars in total: sql, postgresql, mysql, mariadb, sqlite, transactsql, bigquery, redshift, spark, n1ql, db2, and plsql. Pick the one your query was written for, click Format, and the output lands in the right pane indented two spaces per level.

The dialect choice isn't cosmetic. The formatter genuinely parses your statement, so syntax that exists in only one grammar needs that grammar selected. If parsing fails, you'll see the error below the panes instead of half-formatted output.

A JOIN query before and after formatting

Input, exactly as an ORM might log it: SELECT u.id, u.email, COUNT(o.id) AS orders FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE u.created_at >= '2026-01-01' GROUP BY u.id, u.email ORDER BY orders DESC;

One click later, the output reads like a document. Each clause starts its own line:

  • SELECT, with u.id, u.email, and COUNT(o.id) AS orders indented beneath it, one column per line
  • FROM users u
  • LEFT JOIN orders o ON o.user_id = u.id
  • WHERE u.created_at >= '2026-01-01'
  • GROUP BY u.id, u.email
  • ORDER BY orders DESC

Dialect differences in formatting

Every database grew its own habits, and the formatter has to speak them. transactsql wraps identifiers in square brackets, so [Order Details] parses there and nowhere else. mysql and mariadb use backticks for the same job. postgresql brings double-colon casts and dollar-quoted strings, while bigquery table paths like project.dataset.table arrive wrapped in backticks of their own.

Practical rule: when a query refuses to format, the grammar setting is usually wrong before the SQL is. Try the dialect the query actually shipped from, and only then start hunting for a genuine typo. Dialect differences in formatting are the most common reason a perfectly valid statement throws a parse error here.

SQL style for code review, settled once

Formatted SQL changes how review conversations go. With one clause per line, comments attach to a specific join or predicate rather than to the query as a whole. Diffs shrink too: add a column and the diff shows one line, not an entire reflowed statement.

The tool deliberately preserves your keyword casing, so agree on lowercase or uppercase as a team and stick with it. A consistent sql style for code review means nobody wastes a review round trip on whitespace comments again.

Formatting mistakes that hide real bugs

The formatter is simple; the ways teams misuse it are predictable.

  • Reviewing the unformatted original because the formatter errored. Fix the dialect setting instead; unreadable SQL is where bugs go to hide.
  • Reformatting a colleague's query in the same commit as logic changes. The real diff drowns in whitespace noise, so format in a separate commit.
  • Treating a clean format as validation. The parser confirms grammar, not that the join is correct or the index exists.
  • Pasting production literals into tickets. Format first, then swap customer emails and ids for placeholders before sharing.

Two habits that keep long queries readable

First, format at the boundary. Whenever SQL crosses from machine territory to human territory, a log to a ticket, an ORM to a pull request, format it at that moment so nobody downstream reads the compressed version.

Second, keep the readable form in your repo. Migrations, report definitions, and analytics queries should live formatted; the database doesn't care, and every future reader does. When you ask for query help online, paste the formatted version next to your EXPLAIN output and you'll get answers that reference specific lines.

The SQL Formatter next to its neighbors

Query results usually leave the database as JSON or CSV, and those have their own pages. The JSON Formatter indents and validates API-shaped results, while CSV to JSON converts exported rows when a script needs them as objects. And if the SQL lives inside application code that's been minified, run that file through the JS Beautifier first, then bring the extracted query here.

Try it now

Open SQL Formatter

The tool is one click away. No sign up, no upload, no payment.

Open SQL Formatter