How to Format SQL for Readable Code Reviews
Unreadable SQL is a tax on every engineer who touches your codebase. A messy query buried in a migration file or a stored procedure takes longer to review, longer to debug, and longer to refactor. Worse, reviewers skim over dense SQL — which is exactly when dangerous schema changes slip through.
The good news: SQL formatting is mechanical. A few consistent rules make any query readable. This post covers the rules we use at SchemaLens, with before/after examples you can apply today.
Want a head start?
Our free SQL Formatter applies these rules automatically. Paste your query, get clean output.
Format SQL FreeRule 1: One major clause per line
SELECT, FROM, WHERE, JOIN, GROUP BY, ORDER BY, and LIMIT are signposts. Put each on its own line so a reviewer can scan the query structure in milliseconds.
❌ Before
select u.id, u.name, o.total from users u join orders o on u.id=o.user_id where o.status='shipped' and o.total > 100 group by u.id, u.name order by o.total desc limit 10;
✅ After
SELECT
u.id,
u.name,
o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.status = 'shipped'
AND o.total > 100
GROUP BY
u.id,
u.name
ORDER BY o.total DESC
LIMIT 10;
Rule 2: Indent to show hierarchy
Indentation is not decoration — it shows what belongs to what. Columns belong to SELECT. Conditions belong to WHERE. Expressions belong to CASE.
❌ Before
SELECT id, CASE WHEN status = 'active' THEN 1 ELSE 0 END AS is_active, created_at FROM users;
✅ After
SELECT
id,
CASE
WHEN status = 'active' THEN 1
ELSE 0
END AS is_active,
created_at
FROM users;
Rule 3: Align AND and OR operators
When you have multiple conditions, align the boolean operators so the eye can compare predicates vertically.
❌ Before
WHERE status = 'active' AND (email_verified = TRUE OR created_at > '2024-01-01') AND deleted_at IS NULL
✅ After
WHERE status = 'active'
AND (
email_verified = TRUE
OR created_at > '2024-01-01'
)
AND deleted_at IS NULL
Rule 4: Keep lists vertical
Whether it is a column list, a VALUES list, or a set of columns in GROUP BY, put each item on its own line. This makes diffs readable and prevents merge conflicts when two developers add a column at the same time.
❌ Before
INSERT INTO users (id, name, email, phone, address, city, country, created_at) VALUES (1, 'Alice', 'a@example.com', '+1-555-0100', '123 Main St', 'Springfield', 'US', NOW());
✅ After
INSERT INTO users (
id,
name,
email,
phone,
address,
city,
country,
created_at
) VALUES (
1,
'Alice',
'a@example.com',
'+1-555-0100',
'123 Main St',
'Springfield',
'US',
NOW()
);
Rule 5: Use consistent keyword casing
Pick uppercase or lowercase for keywords and stick to it. Mixed casing (select vs SELECT vs Select) makes a query look sloppy and unreviewed.
We prefer uppercase keywords because they stand out from table and column names, making the query structure instantly scannable. But lowercase is fine if your team agrees on it — consistency beats perfection.
Rule 6: Add a trailing comma
This is a style choice, but trailing commas in SELECT lists and column definitions make diffs cleaner. When you add a new line, the diff shows only that line — not the previous line changing its comma.
What about CREATE TABLE and ALTER TABLE?
The same rules apply. One column per line, aligned data types, constraints at the end. If your migration files are formatted consistently, reviewers can spot type changes and missing indexes in a single glance.
For migrations specifically, formatting matters even more. A poorly formatted ALTER TABLE can hide a dropped column or a type narrowing. Vertical formatting forces every change onto its own line, making the diff obvious.
Automate it
Manual formatting is a waste of engineering time. The rules above are 100% mechanical — which means they can be automated.
Use a formatter in your editor, your CI pipeline, or a browser-based tool. The less time you spend pressing Enter and Tab, the more time you spend on logic that actually matters.
Format SQL in your browser
Our free SQL Formatter supports PostgreSQL, MySQL, SQLite, and SQL Server. Paste, format, copy. No signup, no data leaves your device.
Try the SQL FormatterSummary checklist
- One major clause per line (SELECT, FROM, WHERE, JOIN, GROUP BY, ORDER BY, LIMIT)
- Indent to show hierarchy (columns under SELECT, conditions under WHERE)
- Align AND/OR operators vertically
- Put list items on separate lines (columns, VALUES, GROUP BY)
- Use consistent keyword casing across your codebase
- Consider trailing commas for cleaner diffs
- Automate formatting — don't do it by hand
Readable SQL is not a luxury. It is a courtesy to your teammates, your future self, and the production database you are about to modify.
Related reading: The Schema Review Checklist Every Engineering Team Needs · The 5 Most Dangerous Schema Changes · How to Generate ALTER TABLE Scripts Automatically