Guide
How to format SQL for readability
Learn why consistent SQL formatting speeds up review and debugging, the conventions that matter, and how to apply them — with a SQL formatter built in.
SQL is whitespace-insensitive: the engine does not care whether your query is one long line or forty short ones. That freedom is exactly why formatting matters for people. A consistently formatted query is faster to review, easier to debug, and produces smaller, clearer diffs. The tool above applies these conventions in one pass.
Why formatting pays off
A query you wrote yourself five minutes ago is readable in any shape. The same query in a pull request, a bug report, or a six-month-old migration is not. Formatting helps at the moments that cost the most time:
- Review. A reviewer can verify that the right columns are selected and the right tables are joined only if those are visible at a glance.
- Debugging. When a result is wrong, you scan the
WHEREandJOINclauses. Aligned, one-condition-per-line formatting makes a missing or extra predicate jump out. - Diffs. With one column per line, adding a column changes one line in version control instead of rewriting a long line that hides the real change.
Because formatting never affects how the query executes, there is no runtime cost to making it readable.
The conventions that matter
A few rules cover most of what makes SQL readable:
- Keyword case. Uppercase the SQL keywords (
SELECT,FROM,WHERE,JOIN,GROUP BY) so they contrast with lowercase identifiers. Pick one casing and apply it everywhere. - Clause on its own line. Start each major clause on a new line, left-aligned, so the skeleton of the query reads top to bottom.
- One column per line. In the
SELECTlist, give each column its own line. The same applies to longGROUP BYandORDER BYlists. - JOINs aligned. Put each
JOINon its own line underFROM, with itsONcondition close by. - Indent subqueries one level so nesting is visible.
Before and after
The difference is stark on even a small query:
-- before
select u.id, u.name, o.total, o.created_at from users u join orders o on o.user_id = u.id where o.total > 100 and u.active = 1 order by o.created_at desc;
-- after
SELECT
u.id,
u.name,
o.total,
o.created_at
FROM users u
JOIN orders o ON o.user_id = u.id
WHERE o.total > 100
AND u.active = 1
ORDER BY o.created_at DESC;
Both run identically. The second version lets a reviewer confirm in seconds which columns return, which tables join and on what, and which conditions filter the rows — without parsing one dense line.
Dialect notes
The core clauses — SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY — format the
same across every major database. Where dialects diverge is the surrounding syntax:
- Identifier quoting. MySQL uses backticks, PostgreSQL and the standard use double quotes, and SQL Server uses square brackets. A formatter should leave these untouched.
- Row limiting. MySQL and PostgreSQL use
LIMIT; SQL Server usesTOPorOFFSET ... FETCH. - String and date functions. Names and arguments differ between engines, so a formatter focuses on layout rather than rewriting these.
Choosing the matching dialect in the tool above produces output that respects your engine's quoting and limiting syntax. Once a team agrees on a formatting style and applies it on every commit, SQL stops being a wall of text and becomes something you can read like the rest of the codebase.