← Back to Blog

SQL Formatting Best Practices — Why and How to Format Your Queries

Learn SQL formatting conventions, why readable SQL matters, and how to format complex queries for readability and maintainability. Examples in MySQL, PostgreSQL, and SQLite.

Unformatted SQL is one of the biggest causes of bugs in database-heavy applications. A query that was readable when first written becomes unmaintainable after three months of changes. SQL formatting is not optional — it is part of writing professional database code.

Before and After: The Impact of Formatting

SQL
-- ❌ Unreadable (real code seen in production)
SELECT u.id,u.name,u.email,COUNT(o.id) as orders,SUM(o.total) as revenue FROM users u LEFT JOIN orders o ON u.id=o.user_id WHERE u.created_at>'2024-01-01' AND u.status='active' GROUP BY u.id,u.name,u.email HAVING COUNT(o.id)>0 ORDER BY revenue DESC LIMIT 20
SQL
-- ✅ Formatted and readable
SELECT
    u.id,
    u.name,
    u.email,
    COUNT(o.id)   AS orders,
    SUM(o.total)  AS revenue
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE
    u.created_at > '2024-01-01'
    AND u.status = 'active'
GROUP BY
    u.id, u.name, u.email
HAVING COUNT(o.id) > 0
ORDER BY revenue DESC
LIMIT 20

SQL Formatting Rules

  • Keywords in UPPERCASE — SELECT, FROM, WHERE, JOIN, GROUP BY, HAVING, ORDER BY
  • One clause per line — each major clause starts a new line
  • Indent column lists — each selected column on its own indented line
  • Align AS keywords — vertically align aliases for readability
  • Explicit JOIN types — write LEFT JOIN not just JOIN
  • Table aliases — use meaningful short aliases (u for users, o for orders)
  • Parentheses for complex conditions — never guess operator precedence

Formatting Complex WHERE Clauses

SQL
-- ❌ Hard to read conditions
WHERE status='active' AND (role='admin' OR role='editor') AND created_at>'2024-01-01' AND NOT deleted

-- ✅ Each condition on its own line
WHERE
    status = 'active'
    AND (
        role = 'admin'
        OR role = 'editor'
    )
    AND created_at > '2024-01-01'
    AND NOT deleted

Formatting CTEs (Common Table Expressions)

SQL
WITH monthly_revenue AS (
    SELECT
        DATE_TRUNC('month', created_at) AS month,
        SUM(total)                       AS revenue
    FROM orders
    WHERE status = 'completed'
    GROUP BY 1
),

top_customers AS (
    SELECT
        user_id,
        SUM(total) AS lifetime_value
    FROM orders
    GROUP BY user_id
    HAVING SUM(total) > 1000
)

SELECT
    mr.month,
    mr.revenue,
    COUNT(tc.user_id) AS vip_orders
FROM monthly_revenue mr
LEFT JOIN top_customers tc ON TRUE
GROUP BY mr.month, mr.revenue
ORDER BY mr.month

MySQL vs PostgreSQL Differences

FeatureMySQLPostgreSQL
String quotingSingle or double quotesSingle quotes only
Case sensitivityTables case-insensitive on WindowsCase-sensitive by default
Date truncationDATE_FORMAT()DATE_TRUNC()
String concatCONCAT(a, b)a || b or CONCAT(a, b)
Limit syntaxLIMIT 10LIMIT 10 (same)
BooleansTINYINT(1) or BOOLNative BOOLEAN
💡
Use DevToolkit's SQL Formatter to instantly format any SQL query — supports MySQL, PostgreSQL, SQLite, and T-SQL with configurable indentation.