SQL Formatting Standards for Teams
SQL Formatting Standards for Teams
Inconsistently formatted SQL is one of the most common sources of friction in code reviews. When one developer writes compact one-liners and another writes vertically-aligned masterpieces, diffs become unreadable. This guide establishes practical formatting standards.
The Core Rules
Uppercase Keywords
SQL keywords should be uppercase. Column names, table names, and aliases should be lowercase or snake_case.
SELECT
u.id,
u.email,
u.created_at
FROM users u
WHERE u.is_active = true
ORDER BY u.created_at DESC;
One Clause Per Line
Each major clause (SELECT, FROM, WHERE, JOIN, ORDER BY, GROUP BY) starts on a new line at the same indentation level.
SELECT
o.id,
o.total_amount,
c.name AS customer_name
FROM orders o
INNER JOIN customers c ON c.id = o.customer_id
WHERE o.status = 'completed'
AND o.created_at >= '2026-01-01'
ORDER BY o.total_amount DESC
LIMIT 100;
Indentation for Column Lists
Selected columns, conditions, and subexpressions are indented 2 spaces from their parent clause.
SELECT
p.name,
p.price,
CASE
WHEN p.price > 100 THEN 'premium'
WHEN p.price > 50 THEN 'standard'
ELSE 'budget'
END AS tier
FROM products p;
JOIN Formatting
Write the join type explicitly. Never rely on implicit joins (comma-separated FROM). Each ON condition gets its own line if there are multiple conditions.
SELECT
e.name,
d.department_name,
m.name AS manager_name
FROM employees e
INNER JOIN departments d ON d.id = e.department_id
LEFT JOIN employees m ON m.id = e.manager_id
WHERE e.hire_date >= '2025-01-01';
Subquery Formatting
Indent subqueries and give them meaningful aliases.
SELECT
u.name,
recent_orders.order_count
FROM users u
INNER JOIN (
SELECT
customer_id,
COUNT(*) AS order_count
FROM orders
WHERE created_at >= '2026-01-01'
GROUP BY customer_id
) recent_orders ON recent_orders.customer_id = u.id
WHERE recent_orders.order_count > 5;
CTE Formatting
Common Table Expressions (CTEs) should each be clearly separated with their own SELECT block.
WITH monthly_revenue AS (
SELECT
DATE_TRUNC('month', created_at) AS month,
SUM(amount) AS revenue
FROM payments
WHERE status = 'completed'
GROUP BY DATE_TRUNC('month', created_at)
),
revenue_growth AS (
SELECT
month,
revenue,
LAG(revenue) OVER (ORDER BY month) AS prev_revenue
FROM monthly_revenue
)
SELECT
month,
revenue,
ROUND((revenue - prev_revenue) / prev_revenue * 100, 1) AS growth_pct
FROM revenue_growth
ORDER BY month;
Enforcing Standards
Use a SQL formatter in your CI pipeline. Tools like SQLFluff, pgFormatter, or sql-formatter (npm) can auto-format SQL files on commit.
SQLFluff example
sqlfluff lint --dialect postgres queries/
sqlfluff fix --dialect postgres queries/
Conclusion
Pick these rules (or adapt them), document them in your repository, and enforce them with automated formatting. The goal is not perfection but consistency — when all SQL looks the same, reviews focus on logic instead of style.