Skip to content
← Blog

SQL Formatting Best Practices

6 min readGuides

Well-formatted SQL is the difference between a query you can debug in 30 seconds and one that takes 30 minutes. When a query fails at 2 AM, formatting is not cosmetic — it is operational. Yet SQL formatting is inconsistent across teams, with debates about uppercase keywords, indent depth, and comma placement that never resolve.

This guide establishes practical formatting rules with reasoning, so you can pick a style, enforce it, and move on.

Why Format SQL?

Unformatted SQL is common in production:

SELECT u.id, u.name, u.email, o.total, o.created_at FROM users u JOIN orders o ON u.id = o.user_id WHERE o.status = 'completed' AND o.total > 100 ORDER BY o.created_at DESC LIMIT 20;

The same query, formatted:

SELECT
  u.id,
  u.name,
  u.email,
  o.total,
  o.created_at
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.status = 'completed'
  AND o.total > 100
ORDER BY o.created_at DESC
LIMIT 20;

Formatted SQL makes it obvious:

  • Which columns are selected
  • Which tables are joined and how
  • What filters are applied
  • How results are ordered

Rule 1: One Clause Per Line

Each major clause (SELECT, FROM, WHERE, JOIN, ORDER BY, GROUP BY, HAVING, LIMIT) starts on its own line:

SELECT count(*) AS total
FROM orders
WHERE created_at >= '2024-01-01'
  AND status = 'completed'
GROUP BY customer_id
HAVING count(*) > 5
ORDER BY total DESC
LIMIT 10;

Rule 2: Indent Continuation Lines

Columns in SELECT, conditions in WHERE, and join conditions continue with consistent indentation (2 or 4 spaces):

SELECT
  u.name,
  u.email,
  count(o.id) AS order_count,
  sum(o.total) AS lifetime_value
FROM users u

Rule 3: Uppercase Keywords

SQL keywords in UPPERCASE distinguish them from identifiers:

SELECT name FROM users WHERE id = 42 ORDER BY created_at DESC;

Not everyone agrees on this — lowercase keywords are more readable to some developers, and syntax highlighting makes case irrelevant in most editors. Pick one style for your team and enforce it.

Rule 4: One Column Per Line in SELECT

For more than 2-3 columns, put each on its own line:

SELECT
  u.id,
  u.name,
  u.email,
  u.created_at,
  count(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name, u.email, u.created_at;

Rule 5: Align JOINs

Each JOIN gets its own line with the ON condition:

FROM orders o
JOIN users u ON u.id = o.user_id
JOIN products p ON p.id = o.product_id
LEFT JOIN reviews r ON r.order_id = o.id
  AND r.deleted_at IS NULL;

Multi-condition joins indent the additional conditions.

Rule 6: Format CTEs Clearly

Common Table Expressions (CTEs) are the modern way to structure complex queries. Format each CTE as a named block:

WITH monthly_revenue AS (
  SELECT
    date_trunc('month', created_at) AS month,
    sum(total) AS revenue
  FROM orders
  WHERE status = 'completed'
  GROUP BY 1
),
growth AS (
  SELECT
    month,
    revenue,
    lag(revenue) OVER (ORDER BY month) AS prev_revenue,
    round(
      (revenue - lag(revenue) OVER (ORDER BY month))
      / lag(revenue) OVER (ORDER BY month) * 100,
      1
    ) AS growth_pct
  FROM monthly_revenue
)
SELECT *
FROM growth
WHERE growth_pct IS NOT NULL
ORDER BY month;

Rule 7: Subqueries Get Full Formatting

Inline subqueries are formatted with the same rules, indented one level:

SELECT *
FROM users
WHERE id IN (
  SELECT user_id
  FROM orders
  WHERE total > 1000
    AND created_at >= '2024-01-01'
);

Comma Placement: Leading vs Trailing

Trailing commas (more common):

SELECT
  name,
  email,
  created_at

Leading commas (easier to comment out lines):

SELECT
  name
  , email
  , created_at

Both are valid. Pick one for your team. Most formatters default to trailing commas.

Dialect Differences

Different databases have different keywords, functions, and syntax:

FeaturePostgreSQLMySQLSQL ServerSQLite
String concat||CONCAT()+||
Auto incrementSERIAL / GENERATEDAUTO_INCREMENTIDENTITYAUTOINCREMENT
LimitLIMIT nLIMIT nTOP nLIMIT n
BooleanTRUE/FALSE1/01/01/0

A good formatter supports multiple dialects and adjusts keyword recognition accordingly.

Enforcing Consistency

  1. Use an automated formatter — manual formatting drifts. Run a formatter in CI or as a pre-commit hook.
  2. Document your style — one page in your wiki: indent size, keyword case, comma placement, CTE style.
  3. Format on save — editor plugins that format SQL on save eliminate style debates in code review.

Format Your SQL

StackCache SQL Formatter formats SQL for 13 dialects including PostgreSQL, MySQL, SQLite, SQL Server, Oracle, BigQuery, and Snowflake. Paste your query, choose your dialect, and get consistently formatted output — all locally in your browser.

Try it yourself

Open the tool mentioned in this guide — it runs locally in your browser, no account needed.

Open tool