How to Format SQL for Readable Code Reviews

April 21, 2026 · 6 min read · SchemaLens Team

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 Free

Rule 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 Formatter

Summary checklist

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