Formatting SQL in Code Reviews

May 28, 20266 min read

Unformatted SQL is one of the most common sources of friction in code reviews. A developer pastes a query written in a single line, a reviewer asks for better formatting, and the discussion spirals into personal preferences rather than meaningful feedback about logic and performance. Establishing clear SQL formatting standards eliminates this cycle and keeps reviews focused on what matters.

Why SQL Formatting Deserves Its Own Standard

Most teams enforce style guides for their primary programming language — linters catch missing semicolons, inconsistent quotes, and wrong indentation in JavaScript or Python. SQL, however, often lives outside those pipelines. It sits in migration files, ORM scopes, raw query strings, and analytics notebooks, bypassing the linter entirely.

Poorly formatted SQL creates real problems beyond aesthetics:

  • Hidden bugs. A missing comma in a SELECT list or an accidentally commented-out WHERE clause is much harder to spot in a wall of unformatted text.
  • Review slowdown. Reviewers spend cognitive bandwidth parsing layout instead of evaluating JOIN logic, index usage, or N+1 risks.
  • Merge conflicts. When multiple developers edit the same unformatted query without consistent line breaks, Git produces tangled conflicts that are painful to resolve.

Setting Up a Team SQL Style Guide

A practical SQL style guide does not need to be exhaustive. Focus on the rules that have the highest impact on readability and review efficiency.

Core Rules to Define

RuleExampleWhy It Matters
Keyword casingSELECT, FROM, WHERE (uppercase)Keywords stand out from identifiers
Line breaks per clauseEach JOIN, WHERE, ORDER BY on a new lineMakes query structure scannable
Indentation4 spaces per nesting levelShows subquery and CTE boundaries
Comma placementTrailing or leading — pick oneConsistency across all files
Alias styleAS keyword always, or neverPrevents ambiguous shorthand
SemicolonsAlways terminate statementsRequired by some databases, avoids ambiguity

Document your choices in a short markdown file in the repository root. Reference it in pull request templates so authors can self-check before requesting review.

Automating Formatting Checks in CI

Style guides that rely on manual enforcement inevitably drift. The most effective approach is to add a formatting check to your CI pipeline that fails the build on violations.

Using sqlfluff

sqlfluff is a dialect-aware SQL linter and formatter that supports PostgreSQL, MySQL, BigQuery, Snowflake, and more. Configure it with a .sqlfluff file:

[sqlfluff]
dialect = postgres
exclude_rules = L034  # allow mixed select targets

[sqlfluff:layout:type:comma]
line_position = trailing

[sqlfluff:layout:type:select_clause]
line_position = leading

Run it in CI:

# .github/workflows/sql-lint.yml
name: SQL Lint
on: [pull_request]
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install sqlfluff
      - run: sqlfluff lint queries/ --dialect postgres

For auto-fixing, use sqlfluff fix locally. In CI, keep it as a check-only step so developers are forced to run the fix command and review the changes before pushing.

Pre-commit Hooks

For faster feedback, add a pre-commit hook:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/sqlfluff/sqlfluff
    rev: 3.1.1
    hooks:
      - id: sqlfluff-fix
        args: [--dialect, postgres]

This catches formatting issues before they even reach the remote repository, saving CI minutes and review rounds.

Common Formatting Issues to Watch For

Even with automation, certain patterns slip through and deserve explicit attention in reviews:

  • Implicit JOINs. Queries that use comma-separated tables (FROM users, orders) instead of explicit JOIN syntax should be flagged. Explicit JOINs make the relationship between tables clear and reduce the risk of accidental cross joins.
  • **SELECT *. In production queries, wildcard selects should be justified. They break when columns are added or reordered and prevent covering indexes from working efficiently.
  • Missing table aliases. Ambiguous column references without table aliases cause errors in some databases and confusion in all of them.
  • Over-nested subqueries. CTEs (WITH clauses) improve readability over deeply nested subqueries. Encourage their use in the style guide.

Key Takeaways

  • Unformatted SQL wastes review time and hides logic bugs that structured formatting exposes immediately.
  • Define a minimal set of formatting rules — keyword casing, line breaks, indentation, comma placement — and document them in your repository.
  • Automate enforcement with a SQL linter like sqlfluff in CI and pre-commit hooks.
  • Use code reviews to catch semantic issues — implicit JOINs, SELECT *, and over-nested subqueries — rather than debating indentation preferences.

Try It Yourself

Need to clean up SQL before a review? Drop your raw queries into the SQL Formatter to apply consistent keyword casing, indentation, and line breaks in seconds.