SQL · Style · Code Review

SQL Formatting Guide

Readable SQL takes seconds to format and saves hours in code review and incident response. Here is a pragmatic style guide for the queries you write every day.

Before
select u.id,u.email,count(o.id) as total from users u left join orders o on o.user_id=u.id where u.active=true and u.created_at>'2024-01-01' group by u.id,u.email having count(o.id)>5 order by total desc limit 50;
After
SELECT u.id,
       u.email,
       COUNT(o.id) AS total
FROM users AS u
  LEFT JOIN orders AS o
    ON o.user_id = u.id
WHERE u.active = TRUE
  AND u.created_at > '2024-01-01'
GROUP BY u.id,
         u.email
HAVING COUNT(o.id) > 5
ORDER BY total DESC
LIMIT 50;

Why Formatting Beats Cleverness

A production query lives longer than the ticket that produced it, and the person who has to debug it at 3 AM is almost never the person who wrote it. Formatting is the cheapest investment with the biggest return.

One Clause Per Line

Put each major clause (SELECT, FROM, WHERE, GROUP BY, ORDER BY, LIMIT) at the start of a line. The query's shape becomes scannable at a glance; missing joins and forgotten WHERE clauses jump out.

Uppercase Keywords

Keywords in uppercase, identifiers in lowercase. It is a 1980s habit, but it still works: your eye separates control flow from data on contrast alone. Most dialects are case-insensitive for keywords, so this is purely cosmetic — and that is the point.

Column Lists: Comma-First or Comma-Last

Pick one and stick to it. Comma-first (, column) makes it easier to add or remove the last column in a diff. Comma-last is more common and reads more naturally in English. The badchoice is both styles in the same codebase.

Alias Everything

Give every joined table a short alias (users u, orders o) and qualify every column with its alias. When a column later gets added to a joined table, you avoid "ambiguous column" errors and PR churn.

JOIN Readability

LEFT JOIN on its own line, ON indented beneath it. Multiple JOINs stack naturally and the join order becomes obvious. Prefer explicit JOINs over comma-separated FROM lists — implicit cross joins are a classic foot-gun.

WHERE Conditions

One condition per line, with AND / OR at the start of each line (not the end). It makes commenting out a condition a one-line change instead of a two-line one and keeps the operator visible on the left margin where you expect it.

Comments

Use -- … for short notes above a clause, and /* … */for anything spanning more than a line. Explain why you added a window function or picked an index hint, not what the SQL does — well-formatted SQL already shows that.

Dialect Pitfalls

  • Postgres is case-sensitive for quoted identifiers; "User" and User are different
  • MySQL treats '' as a legitimate zero-length string, Postgres treats it as NULL in some contexts
  • SQLite stores dynamic types; a column declared INTEGER happily stores strings
  • MSSQL uses TOP n; everyone else uses LIMIT
  • String concatenation: || (Postgres, SQLite), CONCAT() (MySQL/MSSQL), + (MSSQL only)

Try It

Format any query instantly with our free SQL Formatter. If you are generating INSERT statements from JSON, see the JSON → PostgreSQL tool.

One clause per line

SELECT / FROM / WHERE / GROUP / ORDER each at column zero.

Alias everything

Short table aliases save you from ambiguous-column churn later.

Operators on the left

AND/OR at the start of a line reads better and diffs cleaner.