Skip to content
Spellkit

Why SQL Formatting Matters More Than You Think

SQL layout conventions like one-column-per-line and leading commas aren't aesthetic — they make queries diffable, reviewable, and structurally readable.

SQL is one of the few languages where a 40-line statement is routine and a 400-line one isn't rare. Unlike most code, a query has no functions to break it into pieces — its structure is its layout. That's why SQL formatting conventions are unusually opinionated, and why most of them trace back to two practical goals: making queries diffable and making their shape visible.

One column per line, and why leading commas exist

The most widespread convention is putting each item in the SELECT list on its own line. The reason is version control: when every column shares a line, adding one column rewrites the whole line and the diff shows a wall of change. One column per line means adding, removing, or renaming a column touches exactly one line, and a reviewer sees precisely what changed.

Leading commas — the style where the comma starts the line rather than ending the previous one —

SELECT
    user_id
  , email
  , created_at
FROM users

exist for the same diff-driven reason. With trailing commas, appending a column changes two lines: the new line, plus the previous line which now needs a comma. With leading commas, appending changes one line. There's a second motivation: most SQL dialects reject a dangling comma before FROM, and the most common way to produce one is deleting the last column of a trailing-comma list. Delete a leading-comma line and the list stays syntactically valid. People find the style ugly at first; it persists because it's mechanically safer.

Keyword casing is a highlighting convention from before highlighting

SELECT, FROM, WHERE in uppercase dates from an era of monochrome terminals with no syntax coloring — capitalization was the only way to make structure jump out from identifiers. Editors have done that job with color for decades now, which is why lowercase-keyword styles have gained ground. Neither is more correct (SQL keywords are case-insensitive in every major dialect); what matters is consistency, because mixed casing forces the reader to keep re-checking whether select is a keyword or a column named "select".

Indentation should draw the query's shape

A well-formatted query lets you see its skeleton before reading a single identifier. Joins indented under their FROM show how many tables are involved at a glance. A subquery indented as a block reads as "one derived table" instead of dissolving into its parent. CTE names lined up at the left margin turn a pipeline of transformations into a visible list of steps. The failure mode of unformatted SQL isn't that it can't be read — it's that the reader has to mentally parse nesting that the whitespace could have drawn for them. A six-way join with two correlated subqueries looks identical to a trivial query when it's all one line; formatted, its complexity is honest.

A real formatter parses; it doesn't pattern-match

Naive formatting — inserting a newline before every keyword with find-and-replace — breaks immediately on real SQL. The word from can appear inside a string literal, a comment, or a column name like order_from. A SELECT three subqueries deep needs a different indent than the outer one, and regex has no concept of depth.

An actual SQL formatter works like a compiler front-end: it tokenizes the input (so string literals and comments become opaque single units that can't be mangled), parses the token stream into a syntax tree that mirrors the query's nesting, then prints that tree back out with layout rules applied at each level. That's why a good formatter gets subquery indentation right at any depth, and why formatters need dialect awareness — constructs like PostgreSQL's :: casts or T-SQL's bracketed identifiers have to parse before they can be printed (the differences run deeper than formatting, as covered in how SQL dialects differ).

The best argument: nobody has to argue

Teams that adopt an auto-formatter stop having style debates, for the same reason gofmt ended them in Go and Prettier ended them in JavaScript: once formatting is mechanical, "leading vs trailing commas" stops being a recurring code-review thread and becomes a config line nobody revisits. The formatter's specific choices matter less than the fact that they're nobody's choices. Review comments shift from layout to logic, and every query in the codebase reads the same way regardless of who wrote it — which, for a language where the layout is the structure, is most of the readability battle won up front.

Spellkit's SQL formatter does the parse-and-reprint dance in your browser with selectable dialect, keyword casing, and indent width — paste a one-line query and its actual shape appears.