Unformatted SQL is a maintenance problem. A 200-character single-line query is hard to review in a PR, harder to debug under pressure, and inconsiderate to hand off to a teammate. SQL formatting costs nothing and pays back immediately.
What a SQL Formatter Does
A formatter restructures query text into a consistent, indented layout — without changing what the query does. The database ignores whitespace; formatting is entirely for humans.
Before:
`<code>sql</p>
<p>select u.id,u.name,o.total from users u inner join orders o on u.id=o.user_id where o.status='paid' order by o.total desc limit 100;</p>
</code>
After:
<code>sql
<p>SELECT</p>
<p>u.id,</p>
<p>u.name,</p>
<p>o.total</p>
<p>FROM</p>
<p>users u</p>
<p>INNER JOIN orders o ON u.id = o.user_id</p>
<p>WHERE</p>
<p>o.status = 'paid'</p>
<p>ORDER BY</p>
<p>o.total DESC</p>
<p>LIMIT 100;</p>
</code>
Same query. Dramatically more readable.
Key Formatting Decisions
Keyword case — SQL keywords are case-insensitive. SELECT vs select. Uppercase is the most common convention (keywords stand out visually from identifiers). Choose one and stick to it across your codebase.
Clause alignment — Each major clause (SELECT, FROM, WHERE, GROUP BY, ORDER BY) starts a new line. Conditions within a clause are indented.
Leading vs trailing commas:
`sql
-- Trailing (most common)
SELECT
id,
name,
email
-- Leading (easier to add/remove first item)
SELECT
id
,name
,email
`
AND/OR placement:
<code>sql
<p>-- AND at start of line (easy to comment out one condition)</p>
<p>WHERE</p>
<p>status = 'active'</p>
<p>AND created_at > '2026-01-01'</p>
<p>AND amount > 100</p>
</code>
SQL Dialects
SQL is not one standard. Each database has extensions:
| Database | Notes |
|---|---|
| PostgreSQL | ILIKE, :: casting, $$ dollar quoting, CTEs everywhere |
| MySQL | Backtick identifiers, LIMIT x,y, AUTO_INCREMENT |
| SQLite | Minimal syntax, no stored procedures |
| SQL Server (T-SQL) | TOP, NOLOCK, GETDATE(), GO |
| BigQuery | STRUCT, ARRAY_AGG, UNNEST, standard SQL mode |
A good formatter knows which dialect you're using. SnappyTools' SQL formatter supports all major dialects via a dropdown selector.
Beautification: Compressing SQL Back
The reverse of formatting — collapsing multi-line SQL to a single line — is useful for:
- Embedding SQL in JSON configuration
- Storing queries in environment variables
- Code generation output
- Sending queries in HTTP request bodies
Both directions are available at snappytools.app/sql-formatter-beautifier/.
Automating SQL Formatting in CI
For teams, use sqlfluff:
`bash
pip install sqlfluff
Lint
sqlfluff lint queries/ --dialect postgres
Auto-fix
sqlfluff fix queries/ --dialect postgres
`
.sqlfluff config:
<code>ini
<p>[sqlfluff]</p>
<p>dialect = postgres</p>
<p>indent_unit = space</p>
<p>tab_space_size = 2</p>
</code>
For pre-commit hooks:
<code>yaml
<h1>.pre-commit-config.yaml</h1>
<p>repos:</p>
<p>- repo: https://github.com/sqlfluff/sqlfluff</p>
<p>rev: 3.0.0</p>
<p>hooks:</p>
<p>- id: sqlfluff-lint</p>
<p>args: [--dialect, postgres]</p>
</code>
Anti-Patterns to Avoid
Implicit joins (hard to see the join condition):
`sql
-- Avoid
SELECT * FROM orders, users WHERE orders.user_id = users.id;
-- Better
SELECT * FROM orders INNER JOIN users ON orders.user_id = users.id;
`
SELECT in production — Not formatting, but worth mentioning: always name columns explicitly. SELECT breaks when the schema changes.
Inconsistent keyword case within one query:
`sql
-- Bad
select id FROM users WHERE status='active';
-- Good
SELECT id FROM users WHERE status = 'active';
``
Summary
SQL formatting is about maintainability and team consistency, not performance. Consistent uppercase keywords, clause-per-line layout, and proper indentation make queries reviewable and debuggable. For one-off formatting of queries from APIs, schema dumps, or colleagues: snappytools.app/sql-formatter-beautifier/.
Originally published at https://snappytools.app/sql-formatter-beautifier/