SQLDatabaseBest Practices

SQL Query Formatting Tips

March 2, 2026·6 min read

Well-formatted SQL is not a nicety — it is a professional necessity. Unformatted SQL queries are harder to review in pull requests, harder to debug when something goes wrong, and harder to maintain six months later. This guide covers the formatting conventions used by experienced database engineers and how to apply them consistently.

1. The Case for Consistent Formatting

Compare these two queries — they are functionally identical:

-- Unformatted
select u.id,u.name,count(o.id) as orders from users u left join orders o on u.id=o.user_id where u.active=1 and u.created_at>'2025-01-01' group by u.id,u.name having count(o.id)>0 order by orders desc limit 50
-- Formatted
SELECT
    u.id,
    u.name,
    COUNT(o.id) AS orders
FROM users AS u
LEFT JOIN orders AS o
    ON u.id = o.user_id
WHERE
    u.active = 1
    AND u.created_at > '2025-01-01'
GROUP BY
    u.id,
    u.name
HAVING COUNT(o.id) > 0
ORDER BY orders DESC
LIMIT 50

The formatted version takes 3× more lines but is 10× faster to understand, debug, and modify.

2. Keyword Casing

SQL keywords are case-insensitive, but convention dictates UPPERCASE for all SQL reserved words. This creates a clear visual distinction between keywords and identifiers.

CategoryConventionExamples
SQL KeywordsUPPERCASESELECT, FROM, WHERE, JOIN, GROUP BY, HAVING, ORDER BY
FunctionsUPPERCASECOUNT(), MAX(), COALESCE(), DATE_TRUNC()
Table namessnake_caseuser_profiles, order_items, audit_logs
Column namessnake_casefirst_name, created_at, is_active
Aliasessnake_case or abbreviationu for users, oi for order_items

3. Indentation Rules

  • Each major clause on its own line: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT all start on a new line.
  • Column lists indented: Each item in a SELECT or GROUP BY list indented consistently (2 or 4 spaces — pick one and stick to it).
  • JOIN conditions indented under JOIN: The ON clause is indented one level deeper than the JOIN keyword.
  • WHERE conditions aligned: AND/OR operators at the same indentation level as the first condition, making the logic visually clear.
SELECT
    p.id,
    p.title,
    c.name AS category_name,
    COUNT(r.id) AS review_count,
    AVG(r.rating) AS avg_rating
FROM products AS p
INNER JOIN categories AS c
    ON p.category_id = c.id
LEFT JOIN reviews AS r
    ON p.id = r.product_id
WHERE
    p.is_active = TRUE
    AND p.price BETWEEN 10 AND 500
    AND c.slug != 'archived'
GROUP BY
    p.id,
    p.title,
    c.name
HAVING
    COUNT(r.id) >= 5
ORDER BY avg_rating DESC, review_count DESC
LIMIT 20

4. Common Table Expressions (CTEs)

CTEs (WITH clauses) are one of the most powerful tools for readable SQL. They break complex queries into named, self-documenting steps:

-- Without CTE: deeply nested subqueries (hard to read)
SELECT *
FROM (
    SELECT user_id, COUNT(*) AS order_count
    FROM (
        SELECT * FROM orders WHERE status = 'completed'
    ) AS completed_orders
    GROUP BY user_id
) AS user_stats
WHERE order_count > 10;

-- With CTEs: named, readable steps
WITH completed_orders AS (
    SELECT *
    FROM orders
    WHERE status = 'completed'
),
user_stats AS (
    SELECT
        user_id,
        COUNT(*) AS order_count
    FROM completed_orders
    GROUP BY user_id
)
SELECT *
FROM user_stats
WHERE order_count > 10;

5. Window Functions

-- Window function formatting: OVER clause on the same line or next
SELECT
    id,
    name,
    salary,
    department,
    RANK() OVER (
        PARTITION BY department
        ORDER BY salary DESC
    ) AS dept_salary_rank,
    SUM(salary) OVER (
        PARTITION BY department
    ) AS dept_total_salary
FROM employees
ORDER BY department, dept_salary_rank;

6. Comments in SQL

-- Single-line comment: explain WHY, not WHAT
-- Filter to only include users who completed onboarding
WHERE onboarding_completed_at IS NOT NULL

/* Multi-line comment for complex logic:
   We use LEFT JOIN here instead of INNER JOIN
   because we still want users with zero orders
   to appear in the report with a NULL order count.
*/
LEFT JOIN orders AS o ON u.id = o.user_id

7. SQL Style Guides Worth Reading

  • Simon Holywell’s SQL Style Guide — the most widely-referenced SQL formatting standard
  • dbt Labs SQL Style Guide — tailored for analytics/data engineering workflows
  • GitLab SQL Style Guide — practical guide used in a major open-source company

Pick one style guide for your team and enforce it using an automated SQL formatter.

8. Conclusion

Consistent SQL formatting is a form of respect for your teammates and your future self. UPPERCASE keywords, snake_case identifiers, one clause per line, and CTEs for complex logic are the habits that separate maintainable SQL from impenetrable query soup.

Use our free SQL Formatter to instantly format any SQL query in your browser — supports MySQL, PostgreSQL, and MSSQL dialects.