Skip to main content
Back to module
SQL for Analysis · Readable and Fast SQL

SQL style and comments

Reading24mLesson 1 of 3 in this module

Refactor queries so others can read, review and trust them, with clear layout, aliases, CTEs and comments.

Why it matters

SQL is read far more often than it is written. Your query will be reviewed by a teammate, reused in a dashboard, copied into a scheduled job and debugged by someone at 9 a.m. when the numbers look off. A query that is correct but unreadable is a liability: nobody can check it, so nobody can trust it. Consistent style costs nothing to run and makes mistakes much easier to spot.

A before and after

This query works:

select a.region r,count(distinct a.id) x,sum(b.amount) y from customers a,orders b where a.id=b.customer_id and b.status='completed' group by a.region;

But what are r, x and y? Which tables are a and b? Is the join condition mixed in with the business filter on purpose? Here is the same logic, restyled:

-- Revenue and active customers per region.
-- Business rule: only completed orders count.
WITH completed_orders AS (
  SELECT customer_id, amount
  FROM orders
  WHERE status = 'completed'
)
SELECT c.region,
       COUNT(DISTINCT c.id) AS active_customers,
       SUM(co.amount)       AS revenue
FROM customers AS c
JOIN completed_orders AS co
  ON co.customer_id = c.id
GROUP BY c.region;

Same rows, but each line now says what it does.

The conventions that matter most

There is no single official style, but most team guides (for example the widely shared GitLab and Mozilla data guides, or Simon Holywell's sqlstyle.guide) agree on these points:

1. One clause per line. SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY each start a new line. Long column lists get one column per line.

2. Consistent keyword case. Upper-case keywords (SELECT, FROM) and lower-case names (orders, customer_id) are the most common choice. Lower-case keywords are fine too; what matters is that a file does not mix both.

3. Meaningful aliases with AS. customers AS c and completed_orders AS co are short but recognisable. a, b, t1 force the reader to scroll back. Always alias output columns with names a stakeholder would understand: revenue, not y; active_customers, not x.

4. Explicit joins. Write JOIN ... ON instead of listing tables with commas and putting the join condition in WHERE. The old comma style mixes join logic with filters, and forgetting one condition silently produces a cross join with millions of rows.

5. Qualify columns when more than one table is involved. c.region, not region. When a second table later gains a region column, an unqualified name becomes ambiguous or, worse, refers to the wrong one.

6. CTEs for steps. Each CTE does one job and has a name that describes its rows: completed_orders, customer_totals, ranked_products.

7. No SELECT * in finished queries. List the columns you need. * breaks when someone adds a column and hides what the query actually depends on. (It is fine while exploring.)

8. Trailing or leading commas, consistently. Some teams put commas at the start of lines (, amount) so a column can be commented out easily. Pick one.

Comments: explain why, not what

-- Bad: restates the code
WHERE status = 'completed'  -- status is completed

-- Good: explains the business rule
WHERE status = 'completed'  -- refunds are reported separately by finance

Put a short header at the top of any saved query: what question it answers, the key definitions (what counts as "active"), and anything surprising. Use -- for single lines and /* ... */ for longer blocks.

Readable is also safer

Style is not only cosmetic. Formatting each condition on its own line makes AND/OR precedence visible:

WHERE status = 'completed'
  AND (region = 'North' OR region = 'South')

Without the brackets, a AND b OR c means (a AND b) OR c, which would include every South order whatever its status. Clear layout makes that bug jump out in a review.

Formatters and linters

You do not have to format by hand. SQLFluff is a free, open source linter and formatter that supports many dialects and can enforce a team style in CI. Most editors (VS Code, DataGrip, DBeaver) have a "format SQL" command. Agree on the settings once, then let the tool do it.

Common mistakes

  • Single-letter or numbered aliases (a, t1) in a query longer than a few lines.
  • Cryptic output names that leak into dashboards and spreadsheets.
  • Comma joins with the join condition hidden in WHERE.
  • Mixing AND and OR without brackets.
  • Comments that repeat the code instead of explaining the reason.

Quick recap

  • One clause per line, consistent keyword case, explicit JOIN ... ON.
  • Meaningful table aliases and business-friendly column names.
  • CTEs for steps; comments for business rules.
  • Use a formatter such as SQLFluff to keep a team consistent.

Try it

Open the Do tab and refactor a one-line query into a readable, commented one with clear column names.

Also in this lesson: