SQL doesn't care about whitespace. SELECT*FROM users WHERE id=1 works just as well as a perfectly indented, keyword-capitalised query. But your teammates, your future self, and your code reviewer absolutely care.
Here's why formatting matters — and what a good SQL style looks like.
Readability compounds
A 3-line query formatted badly is annoying. A 50-line query with joins, subqueries, and multiple CTEs formatted badly is a debugging nightmare. Consistent formatting makes the structure of a query visible at a glance.
Compare:
-- Unformatted
select u.name,o.total,p.name as product from users u join orders o on u.id=o.user_id join order_items oi on o.id=oi.order_id join products p on oi.product_id=p.id where o.created_at>'2024-01-01' and o.status='completed' order by o.total desc limit 20;
-- Formatted
SELECT
u.name,
o.total,
p.name AS product
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE
o.created_at > '2024-01-01'
AND o.status = 'completed'
ORDER BY o.total DESC
LIMIT 20;
Same query. The second one makes the join chain obvious, the filter conditions easy to scan, and the intent clear in 3 seconds.
Key formatting conventions
1. Uppercase keywords
SELECT, FROM, WHERE, JOIN, ON, AND, ORDER BY in uppercase. Column names and table names in lowercase (or match your database's casing). This visual contrast is the single biggest readability win.
2. One clause per line
Each major clause (SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT) starts on a new line at the left margin.
3. Indent continuation lines
Items in a SELECT list or WHERE conditions are indented one level from their clause keyword.
4. Align ON conditions in JOINs
JOIN orders o
ON u.id = o.user_id
JOIN order_items oi
ON o.id = oi.order_id
5. Use table aliases consistently
If you alias users as u, use u. everywhere — never mix users.column and u.column in the same query.
6. End every statement with a semicolon
Even if your client doesn't require it, the semicolon makes the statement boundary explicit when queries are batched.
CTEs are your friend for complex queries
Instead of nested subqueries, use CTEs (WITH clauses) to name each logical step:
WITH recent_orders AS (
SELECT *
FROM orders
WHERE created_at > '2024-01-01'
AND status = 'completed'
),
order_totals AS (
SELECT user_id, SUM(total) AS lifetime_value
FROM recent_orders
GROUP BY user_id
)
SELECT u.name, ot.lifetime_value
FROM users u
JOIN order_totals ot ON u.id = ot.user_id
ORDER BY ot.lifetime_value DESC;
Each CTE is a named, readable step. The final SELECT reads almost like English.
Formatting inherited or minified SQL
When you inherit a codebase or export from a query builder, the SQL often arrives as one dense block. Paste it into the SQL Formatter on SnappyTools to get properly indented, keyword-uppercased output instantly. It handles MySQL, PostgreSQL, SQLite, and T-SQL dialects, runs entirely in your browser, and produces clean output ready to paste back into your codebase.
SQL style doesn't affect performance — but it dramatically affects maintainability. Establish a formatting convention on your team, run your queries through a formatter before code review, and future-you will thank present-you.
Top comments (0)