5 SQL Formatting Rules That Make Your Queries Actually Readable

Published: (March 15, 2026 at 12:49 AM EDT)
3 min read
Source: Dev.to

Source: Dev.to

We’ve all been there — you inherit a project, open a stored procedure, and it’s one giant wall of SQL. No indentation, no structure, just chaos. Or maybe you wrote it yourself six months ago and now you can’t even tell what it does.

After years of writing SQL professionally, here are five formatting rules I follow that make my queries actually readable — both for my teammates and for future me.

Rule #1: One clause per line

Each major SQL clause gets its own line.

Bad

SELECT u.id, u.name, u.email, o.total FROM users u JOIN orders o ON u.id = o.user_id WHERE o.created_at > '2024-01-01' AND u.active = 1 ORDER BY o.total DESC;

Good

SELECT u.id, u.name, u.email, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.created_at > '2024-01-01'
  AND u.active = 1
ORDER BY o.total DESC;

Instantly more scannable. You can immediately see the tables involved, the join condition, and the filters.

Rule #2: Leading commas

Leading commas make it trivial to comment out or add columns.

SELECT
  u.id
  , u.name
  , u.email
  , u.created_at
  -- , u.phone  (easy to toggle!)
FROM users u

When you need to remove a column, you don’t have to worry about trailing‑comma issues—just comment the line out.

Rule #3: Keep CTEs clean

CTEs (WITH clauses) are powerful but can get messy fast. Keep each CTE a clear, self‑contained block.

WITH active_users AS (
  SELECT id, name, email
  FROM users
  WHERE active = 1
    AND last_login > '2024-06-01'
),
recent_orders AS (
  SELECT user_id, SUM(total) AS total_spent
  FROM orders
  WHERE created_at > '2024-01-01'
  GROUP BY user_id
)
SELECT
  au.name
  , au.email
  , ro.total_spent
FROM active_users au
JOIN recent_orders ro ON au.id = ro.user_id
ORDER BY ro.total_spent DESC;

Rule #4: Visual hierarchy

Create a clear visual hierarchy by aligning keywords and clauses.

SELECT u.name, COUNT(*) AS order_count
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE u.country = 'US'
GROUP BY u.name
HAVING COUNT(*) > 5
ORDER BY order_count DESC;

Your eyes can scan the keywords to understand the query structure without reading every detail.

Rule #5: Use automated formatters

Manual formatting isn’t always consistent, especially in a team setting. Automated formatters handle most of these rules for you.

  • SQLNice – a free online SQL formatter.
  • Built‑in IDE formatters (DataGrip, DBeaver).
  • CLI tools like sql-formatter or pgFormatter.

Benefits of clean SQL

  • Code review speed – reviewers can spot issues faster.
  • Debugging – isolate problems when each clause is on its own line.
  • Onboarding – new team members can read queries without a Rosetta Stone.
  • Version control – clean diffs when each element has its own line.

SQL formatting is one of those small investments that pays off every single day. Start with rule #1 (one clause per line) and build from there.

What formatting conventions does your team follow? Drop a comment—I’m always looking to improve my SQL game.

0 views
Back to Blog

Related posts

Read more »

A Small Habit That Improves Code Quality

One simple habit that helped me improve my code is using clear and descriptive names. Instead of writing variables like x, data, or temp, I try to name them acc...

Branching Without Fear

Part 3 of the Git Mastery Series ← Part 2: Committing with Intentionhttps://dev.to/itxshakil/committing-with-intention-the-art-of-a-good-commit-p90 | Part 4: C...