SQL Formatting Best Practices With Examples
A practical SQL style guide: keyword case, clause layout, joins, aliases, CTEs, commas and comments, with before-and-after examples.
Editorial disclosure: Pyalm publishes and maintains the products and free tools discussed on this site. Regulatory statements are linked to primary sources where applicable. No independent professional review is claimed unless a reviewer is explicitly named.
Most SQL bugs hide in queries nobody can read. Consistent formatting doesn't change what a query does, but it changes how quickly a human can see what it does — and whether a code review catches the mistake.
Before and after
Hard to read:
select o.id,c.name,sum(oi.qty*oi.price) total from orders o join customers c on c.id=o.customer_id join order_items oi on oi.order_id=o.id where o.status='paid' and o.created_at>='2026-01-01' group by o.id,c.name order by total desc limit 50;
Readable:
SELECT
o.id,
c.name,
SUM(oi.qty * oi.price) AS total
FROM orders o
JOIN customers c
ON c.id = o.customer_id
JOIN order_items oi
ON oi.order_id = o.id
WHERE o.status = 'paid'
AND o.created_at >= '2026-01-01'
GROUP BY o.id, c.name
ORDER BY total DESC
LIMIT 50;
The rules worth adopting
- Capitalise keywords (SELECT, FROM, WHERE) and keep identifiers in lower snake_case. It makes the skeleton stand out.
- One clause per line. SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING and ORDER BY each start a line.
- One column per line in the SELECT list once there are more than two or three. Diffs then show exactly which column changed.
- Put each JOIN's ON condition on its own indented line. Always use explicit JOIN syntax, not comma joins.
- Align AND / OR at the start of lines in WHERE; add parentheses when mixing them.
a AND b OR cdoesn't mean what many people think. - Alias with AS and use short but meaningful aliases (o for orders, not t1).
- Qualify columns with the alias whenever more than one table is involved.
- Avoid SELECT \* in application code — it breaks when columns change and fetches more than needed.
- Use CTEs (WITH) to name the steps of a complex query instead of deeply nested subqueries.
- Comment the why, not the what.
Trailing vs leading commas
Trailing commas are the common default. Leading commas (, column) make it easy to comment out or append a column without touching the previous line, which some teams prefer. Pick one and enforce it.
A CTE example
WITH paid_orders AS (
SELECT id, customer_id
FROM orders
WHERE status = 'paid'
)
SELECT c.name, COUNT(*) AS orders
FROM paid_orders po
JOIN customers c
ON c.id = po.customer_id
GROUP BY c.name;
Money and dates in SQL
- Store money as integers in minor units or as
NUMERIC/DECIMAL, never floating point — see floating-point money bugs. - Store timestamps in UTC and convert at the edges.
- Filter dates with half-open ranges (
>= start AND < end) rather than BETWEEN.
Enforcing a style
- Use a formatter in your editor or pre-commit hook so style isn't a review topic.
- Check it in CI.
- Format queries embedded in code consistently with the rest of the repository.
Format a query instantly
Paste any query into the free SQL Formatter for clause-per-line layout, indented joins and conditions, uppercase keywords and a choice of indent and comma style — or minify it for a one-line config value. Strings, comments and quoted names are never altered, and nothing is uploaded. Compare a before-and-after with the Text Diff Checker.
When your queries outgrow the app
Complex reporting queries, slow dashboards and spreadsheet-driven data workflows are often a sign you need a proper data layer. See custom software development process and cost or talk to Pyalm.