SQL Formatting & Pretty Print: CTEs, Joins & Review-Friendly Diffs
Data teams search SQL formatter online, SQL pretty print, and sqlfluff when one-line queries hide bugs. Readable SELECT lists, aligned JOIN predicates, and WITH clauses (CTEs) reduce review time and onboarding friction—especially when analytics SQL mixes window functions, GROUP BY rollups, and vendor hints. This guide covers style rules, dialect quirks, and CI automation without promising phantom performance gains from whitespace alone.
Structure: SELECT columns, JOIN alignment, WHERE clarity
Put each SELECT projection on its own line; trailing commas simplify diffs. Align JOIN blocks so reviewers see how tables relate—inner vs left matters for cardinality bugs. Push filters to WHERE for readability unless outer join semantics require predicates in the join clause.
SELECT
u.id,
u.email,
o.total
FROM users AS u
LEFT JOIN orders AS o
ON o.user_id = u.id
WHERE u.created_at >= DATE '2026-01-01';CTEs vs nested subqueries
Common Table Expressions break complex pipelines into named steps—easier to unit-test mentally and often clearer in EXPLAIN reviews. Some optimizers inline CTEs differently; profile hot paths rather than assuming performance, but default to clarity until metrics say otherwise.
Review tip
Ask "what breaks if a duplicate row appears?" when reading joins—formatting makes missing DISTINCT or GROUP BY obvious.
Formatting traps
Hidden trailing spaces in VARCHAR keys, case-sensitive collations, and dialect-specific string concatenation (|| vs +) still bite teams who only fixed whitespace. Formatting complements tests, not replaces them.
Team style guides, sqlfluff, and noise-free pull requests
Agree on column order (keys first vs domain first), alias rules (AS always vs never), and whether tabs or spaces win—then encode the rules in sqlfluff or your formatter's config. Checking formatted SQL in CI prevents "whitespace-only" bikeshedding in review. When onboarding data analysts, point them at the same snippets you use in docs so examples do not drift from production views. For pipelines that emit JSON, keep warehouse extracts aligned with our JSON formatting guide.
Large migrations deserve extra structure: separate ALTER blocks, comment ticket IDs, and avoid mixing refactors with logic changes in one commit—reviewers cannot diff intent when everything moves at once.
Window functions, QUALIFY, and analytics readability
Window functions (ROW_NUMBER, RANK, LAG) get dense fast—format each partition and order clause on its own line. Snowflake's QUALIFY filters window results without nested subqueries; BigQuery shares similar patterns. Name windows explicitly when databases allow it so explain plans map back to source. If you export result sets for CSV cleaning or BI tools, consistent SQL aliases become column headers—another reason to avoid t1, t2 laziness in shared queries.
Security reviews: SQL injection vs formatting
Pretty SQL in application code does not fix injection—parameterized queries and least-privilege roles do. During review, still flag string-built SQL even if indentation is perfect. For stored procedures, format defensively around dynamic SQL blocks where concatenation is unavoidable, and cross-check with your synthetic data policies so test fixtures never echo live customer literals into logs.
Recommended tools on Universal Dev Tools
Quick beautify for ad hoc queries before you paste into docs or tickets.
Pretty-print API payloads that mirror your query results in integration tests.
Compare query versions side by side when refactoring long analytics scripts.
Clean lists of table or column names exported from spreadsheets before scripting migrations.
Related guides on this blog
Frequently Asked Questions
Does SQL formatting change query execution plans?
Whitespace and capitalization do not change the logical meaning of SQL for mainstream databases—the optimizer parses to the same tree. Formatting is for humans; however, some ORMs embed comments or hints where spacing matters—verify vendor docs.
How do I format SQL for MySQL vs PostgreSQL vs SQL Server?
Dialects differ on string quotes, identifiers, LIMIT/TOP, and functions. Choose a formatter with dialect presets or agree on a portable subset for documentation snippets.
Should SQL keywords be uppercase?
Consistency matters more than dogma. Uppercase keywords with snake_case identifiers is a common convention; match generated SQL from your ORM to reduce noisy diffs.
What about formatting stored procedures and PL/pgSQL blocks?
Procedural blocks need indentation for nested BEGIN/END. Some formatters struggle—fallback to manual structure or vendor-specific beautifiers.
Can I auto-format SQL in CI?
Yes—run sqlfluff, sql-formatter, or equivalent in pre-commit. Fail builds when marketing docs drift from canonical queries to keep examples trustworthy.
Why use CTEs (WITH clauses) in complex SQL?
Common Table Expressions clarify multi-step logic, enable reuse within a statement, and make diffs readable compared to nested subqueries—especially in analytics reviews.
Wrapping up
Adopt a SQL style guide, enforce it in CI, and keep exploratory queries formatted before they ossify into "tribal knowledge" views.
SQL Formatter →