SQL is supposed to be readable — that was the whole point when IBM designed it in the 1970s. But somewhere between auto-generated ORM queries, copy-pasted snippets, and 200-character WHERE clauses on a single line, most production SQL becomes nearly impossible to scan. Formatting fixes that. Here's the practical guide to formatting SQL well.
What SQL Formatting Actually Does
Formatting SQL means restructuring the same query so that clauses, joins, and conditions sit on their own lines with consistent indentation. The query is logically identical — only the whitespace changes.
Unformatted:
SELECT u.id, u.name, COUNT(o.id) as orders FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE u.created_at > '2025-01-01' AND u.status = 'active' GROUP BY u.id, u.name HAVING COUNT(o.id) > 5 ORDER BY orders DESC LIMIT 10;
Formatted:
SELECT
u.id,
u.name,
COUNT(o.id) AS orders
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2025-01-01'
AND u.status = 'active'
GROUP BY u.id, u.name
HAVING COUNT(o.id) > 5
ORDER BY orders DESC
LIMIT 10;
The formatted version takes longer to read top-to-bottom but lets you scan the structure: select clause, source, joins, filters, grouping, ordering. That structure is what matters in code review.
Why You Should Format SQL
Code review. Reviewers can spot a missing JOIN condition or a misplaced WHERE filter when each clause sits on its own line. In one-line SQL, a missing AND is easy to miss.
Debugging. When a query returns wrong results, you isolate the bug by reading clauses individually. Formatting makes that possible.
Diffs. Git diffs on formatted SQL show exactly which line changed. Reformatting an entire query in the same commit as a logic change makes the real change invisible.
Onboarding. New engineers reading legacy queries spend 80% of their time understanding what the query does. Formatting cuts that time roughly in half.
SQL Formatting Conventions
There's no single "correct" SQL style, but most modern style guides converge on a few rules:
Keywords uppercase. SELECT, FROM, WHERE — not select, from, where. The visual distinction between SQL keywords and identifiers helps scanning. (Some teams do all-lowercase; pick one and be consistent.)
One column per line in SELECT. Easier to add, remove, and comment out individual columns.
JOIN type on the same line as the table. LEFT JOIN orders o, not LEFT\n JOIN orders o.
ON conditions inline with JOIN. LEFT JOIN orders o ON o.user_id = u.id.
WHERE conditions stack with leading AND/OR. Leading conjunctions (AND at the start of the line) make it obvious which conditions are connected:
WHERE u.status = 'active'
AND u.created_at > '2025-01-01'
AND u.deleted_at IS NULL
Indent subqueries and CTEs consistently. 2 or 4 spaces — never tabs (tabs render differently in different editors).
How to Format SQL Online
Use DevZone's SQL Formatter to format SQL in one paste:
- Paste your query into the input pane.
- The formatter detects the dialect and produces a properly indented version.
- Configure indent size (2 or 4 spaces), keyword case (UPPER, lower, Capitalize), and comma placement.
- Copy the result back into your code, migration file, or pull request.
The formatter handles all major dialects — Postgres, MySQL, SQLite, SQL Server, BigQuery, Snowflake, Redshift — including dialect-specific keywords.
Dialect Differences That Matter for Formatting
Different SQL dialects use different keywords and case sensitivity rules. A formatter that doesn't know your dialect can mangle valid syntax.
| Dialect | Notable Quirks |
|---|---|
| PostgreSQL | RETURNING, ILIKE, :: cast operator |
| MySQL | Backticks for identifiers, LIMIT offset, count |
| SQL Server | Square brackets for identifiers, TOP instead of LIMIT |
| BigQuery | STRUCT, ARRAY, EXCEPT after SELECT |
| Snowflake | QUALIFY, MATCH_RECOGNIZE |
| SQLite | Limited ALTER TABLE, no FULL JOIN |
When you format SQL, set the right dialect — otherwise you may lose backticks, get a LIMIT rewritten as TOP, or have legitimate keywords flagged as identifiers.
Formatting in Common Tools
psql: Use \e to open the current query in your $EDITOR, format it there, then re-execute.
VS Code: Install the "SQL Formatter" extension, then Shift+Alt+F to format. Configure the dialect in settings.
DBeaver: Right-click query → Format → Format SQL. Configure formatting rules under Preferences → Editors → SQL Editor → SQL Format.
DataGrip: Code → Reformat Code (Ctrl/Cmd + Alt + L). DataGrip's formatter is dialect-aware out of the box.
dbt: Use sqlfmt or sqlfluff for project-wide formatting and linting. Both can run as pre-commit hooks.
When NOT to Auto-Format SQL
Reformatting committed SQL on a whim creates noisy diffs that bury real changes. Don't do it casually — at minimum:
- Reformat in its own commit, separate from logic changes.
- Get team agreement on a style before bulk-reformatting old files.
- Add the formatter to pre-commit so new code stays consistent without manual work.
FAQ
Should SQL keywords be uppercase or lowercase?
Both are valid SQL. Most public style guides (Mozilla, GitLab, dbt) recommend UPPERCASE keywords because the visual contrast helps reading. A few modern shops prefer all-lowercase. Pick one and enforce it with a formatter — mixing styles is the only wrong answer.
How do I format SQL inside a string in my code?
Many languages have SQL-aware formatters that respect language strings:
- Python:
sqlparselibrary, orblackplus a SQL plugin - JavaScript:
prettier-plugin-sqlfor template literals tagged withsql`...` - Go:
gosqlformatters
Tagging template literals (e.g., sql\SELECT ...``) gives editors and formatters the hint they need to apply SQL formatting inside strings.
Does formatting affect query performance?
No. The query optimizer parses your SQL into an abstract syntax tree before execution. Whitespace and case have zero effect on how a query runs. Two queries that format differently produce identical execution plans.
What's the difference between formatting and linting SQL?
Formatting is mechanical — it changes whitespace and case to match a style. Linting is opinionated — it flags antipatterns like SELECT *, missing aliases, or implicit cross joins. Tools like sqlfluff do both; basic formatters only handle whitespace.
Can I format CTEs and window functions?
Yes — any modern SQL formatter handles CTEs (WITH ... AS (...)), recursive CTEs, and window functions (OVER (PARTITION BY ...)). Make sure your formatter knows the dialect, since some functions (like QUALIFY) only exist in BigQuery, Snowflake, or Teradata.