SQL Formatter
Format and beautify SQL queries instantly. Paste messy SQL code and get clean, indented, readable output with syntax highlighting.
Key features
- Automatic keyword uppercasing
- Configurable indentation
- Syntax highlighting
- Support for common SQL dialects
Guide
SQL formatting transforms dense, unreadable queries into structured, consistently indented code that is easy to read, review, debug, and maintain. A query that works perfectly when written as a single line becomes a maintenance burden when someone else (or you, three months later) needs to understand what it does. Consistent SQL formatting is not cosmetic. It reduces bugs, speeds up code review, and makes complex queries tractable. This guide covers formatting conventions, clause structure, common patterns for different query types, and how formatting interacts with query optimization. The foundational rule of SQL formatting is one clause per line. SELECT, FROM, WHERE, JOIN, ON, GROUP BY, HAVING, ORDER BY, LIMIT, INSERT INTO, VALUES, UPDATE, SET, and DELETE FROM each start on their own line at the base indentation level. This structure makes the query scannable. You can see at a glance what columns are selected, which tables are involved, what conditions filter the data, and how the results are ordered. A query formatted this way reads like a structured document rather than a run-on sentence. SELECT clause formatting lists each column on its own line, indented one level from the SELECT keyword. Leading commas (commas at the beginning of each line rather than the end) are a popular convention because they make it easy to comment out individual columns and produce cleaner diffs in version control. Both trailing and leading commas are acceptable as long as the choice is consistent across the codebase. Column aliases should use the AS keyword explicitly (column_name AS alias) rather than the shorthand (column_name alias) for clarity. When a column expression is long (a CASE statement or a function call with multiple arguments), place it on its own line and indent the continuation. FROM and JOIN clauses benefit from consistent alignment. Each JOIN gets its own line at the same indentation as FROM. The ON condition is indented below its JOIN. For queries with many joins, this visual structure makes the table relationships clear: FROM orders o JOIN customers c ON c.customer_id = o.customer_id JOIN products p ON p.product_id = o.product_id LEFT JOIN shipping s ON s.order_id = o.order_id The join type (INNER JOIN, LEFT JOIN, RIGHT JOIN, CROSS JOIN, FULL OUTER JOIN) carries meaning. Formatting that visually separates each join helps reviewers verify that the correct join type is used for each relationship. A LEFT JOIN that should be an INNER JOIN (or vice versa) is a common bug that formatted code makes easier to spot. WHERE clause formatting places each condition on its own line with AND or OR at the beginning of the line. Indenting conditions below WHERE makes the filter logic visible: WHERE o.order_date >= '2026-01-01' AND o.status = 'completed' AND c.country = 'US' AND (p.category = 'electronics' OR p.category = 'appliances') Complex boolean logic with mixed AND and OR operators is a common source of bugs. Formatting with explicit parentheses and clear indentation shows the logical grouping. Without formatting, WHERE a = 1 AND b = 2 OR c = 3 is ambiguous to human readers (though SQL evaluates AND before OR, so it means (a = 1 AND b = 2) OR c = 3). Formatted with parentheses, the intent becomes clear. Always use parentheses with mixed AND/OR to make precedence explicit. Subqueries should be indented one level inside their parentheses. Each subquery is formatted using the same rules as a top-level query. Correlated subqueries (those referencing columns from the outer query) are particularly important to format clearly because their relationship to the outer query determines their behavior: SELECT customer_name , total_spent FROM customers c WHERE total_spent > ( SELECT AVG(total_spent) FROM customers WHERE country = c.country ) The indentation shows that the subquery is nested inside the WHERE clause and references c.country from the outer query. For deeply nested subqueries (three or more levels), consider refactoring to CTEs instead, as deep nesting becomes hard to follow regardless of formatting. Common Table Expressions (CTEs) using WITH clauses should be formatted with each CTE as a separate named block: WITH monthly_sales AS ( SELECT DATE_TRUNC('month', order_date) AS month , SUM(amount) AS total FROM orders GROUP BY DATE_TRUNC('month', order_date) ), monthly_avg AS ( SELECT AVG(total) AS avg_total FROM monthly_sales ) SELECT m.month , m.total , a.avg_total FROM monthly_sales m CROSS JOIN monthly_avg a WHERE m.total > a.avg_total CTEs are one of the most powerful SQL features for breaking complex queries into readable, testable components. Each CTE can be tested independently by running just its SELECT statement. Proper formatting makes each CTE's purpose visible and the data flow between CTEs traceable. Name your CTEs descriptively: monthly_sales is better than cte1. GROUP BY and ORDER BY clauses follow the same multi-line pattern as SELECT when they reference multiple columns. List each column on its own indented line. For GROUP BY, this makes it easy to verify that all non-aggregated SELECT columns are included (a requirement in standard SQL and enforced by PostgreSQL, though MySQL is permissive by default). For ORDER BY, listing each sort column with its direction (ASC or DESC) on a separate line clarifies the sort priority. Explicitly stating ASC (even though it is the default) improves readability. HAVING clause formatting follows the same rules as WHERE. HAVING filters groups after aggregation, and its conditions should be formatted with one condition per line. A common formatting mistake is placing HAVING conditions in the WHERE clause or vice versa. WHERE filters rows before grouping. HAVING filters groups after aggregation. Correct placement is essential for both correctness and performance, and clear formatting makes it easy to verify. CASE expressions are multi-line constructs that should be formatted to show each WHEN/THEN pair: SELECT order_id , CASE WHEN status = 'shipped' THEN 'In Transit' WHEN status = 'delivered' THEN 'Complete' WHEN status = 'returned' THEN 'Returned' ELSE 'Processing' END AS status_label FROM orders Nested CASE expressions (CASE inside CASE) should be avoided when possible because they become unreadable regardless of formatting. Refactor into CTEs, computed columns, or a lookup table joined into the query instead. INSERT statements have two common formats. For single-row inserts with named columns, list each column-value pair readably: INSERT INTO customers ( customer_name , email , country , created_at ) VALUES ( 'John Doe' , 'john@example.com' , 'US' , CURRENT_TIMESTAMP ) Aligning the VALUES entries with their corresponding column names makes it easy to verify that each value matches the correct column. For INSERT...SELECT statements, format the SELECT portion using standard SELECT formatting rules. UPDATE statements benefit from formatting each SET assignment on its own line: UPDATE customers SET email = 'newemail@example.com' , updated_at = CURRENT_TIMESTAMP , status = 'verified' WHERE customer_id = 12345 This structure makes it clear which columns are being modified and prevents accidentally omitting the WHERE clause, which would update every row in the table. The WHERE clause in UPDATE and DELETE statements is the most critical clause to get right. Formatting that puts the WHERE on its own line at the same level as UPDATE or DELETE makes its presence (or absence) obvious. DELETE statements should always have their WHERE clause clearly visible: DELETE FROM order_items WHERE order_id = 12345 AND item_status = 'cancelled' A DELETE without WHERE removes all rows from the table. Formatted code makes the presence or absence of WHERE immediately visible. Some teams adopt a convention of always writing DELETE queries as SELECT queries first (replacing DELETE FROM with SELECT * FROM) to verify which rows will be affected, then converting back to DELETE. Window functions are among the most complex SQL constructs to format. The OVER clause with PARTITION BY and ORDER BY should be on their own indented lines when they are long: SELECT customer_id , order_date , amount , SUM(amount) OVER ( PARTITION BY customer_id ORDER BY order_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS running_total FROM orders For short window specifications, keeping them on one line is acceptable: ROW_NUMBER() OVER (ORDER BY id) AS row_num. The goal is readability at the length and complexity of the actual expression. Named window definitions (WINDOW w AS (PARTITION BY customer_id ORDER BY order_date)) followed by OVER w reduce repetition when multiple columns use the same window specification. Keyword capitalization is a style choice with strong opinions on both sides. UPPERCASE keywords (SELECT, FROM, WHERE) visually distinguish SQL syntax from table and column names. Lowercase keywords blend in but are easier to type. The most important thing is consistency. Pick one convention and enforce it across the team. Many organizations use uppercase for keywords and lowercase for identifiers. Some modern style guides prefer all lowercase for everything, arguing that syntax highlighting in editors already distinguishes keywords from identifiers. A third approach capitalizes only the major clause keywords (SELECT, FROM, WHERE) and leaves function names and minor keywords lowercase. Table aliases should be meaningful. Using single-letter aliases (a, b, c) saves typing but makes queries harder to read, especially with many joins. Short abbreviations derived from the table name are better: customers AS c, orders AS o, order_items AS oi. In complex queries with many tables, longer aliases improve clarity: customers AS cust, order_items AS items. Always use the AS keyword for aliases to distinguish them from typos or forgotten commas. Never use reserved words as aliases. Indentation width should be consistent. Two spaces and four spaces are both common choices. Tabs versus spaces is a preference, but spaces produce more consistent alignment across editors and tools. The SQL formatter tool lets you configure indentation width to match your team's standard. Whichever width you choose, use it uniformly for all indentation levels: clause body, subquery nesting, CASE expression bodies, and CTE definitions. Comment formatting in SQL uses -- for single-line comments and /* */ for multi-line comments. Place comments above the clause or expression they describe, not inline at the end of a long line where they might be missed. For complex business logic in WHERE clauses, a comment explaining why a condition exists is valuable: -- Exclude test accounts created by QA team before the filter condition. Comments that restate the SQL (-- Join customers table) add noise without value. Good comments explain intent, not mechanics. Formatting and query performance are not directly related. The database engine parses and optimizes the query regardless of whitespace and line breaks. However, well-formatted queries are easier to optimize because you can see the structure clearly. A poorly formatted query with a performance problem hides the issue in a wall of text. The same query, properly formatted, reveals the problematic subquery, missing join condition, unnecessary DISTINCT, or non-sargable WHERE clause at a glance. Formatting is a debugging and optimization tool. Version control and SQL formatting interact in important ways. Reformatting an entire query in a single commit produces a diff that touches every line, making it impossible to see what actually changed. When adopting a formatter for an existing codebase, do the formatting in a dedicated commit with a clear message like "Apply SQL formatting standard." Subsequent changes then produce clean, meaningful diffs. Leading commas are popular partly because adding a new column to a SELECT produces a one-line diff (the new line), whereas trailing commas require modifying the previous line to add a comma, creating a two-line diff. Dialect differences affect formatting choices. PostgreSQL, MySQL, SQL Server, Oracle, SQLite, and BigQuery each have syntax variations. PostgreSQL uses double-colon casting (value::type) and dollar-quoted strings. MySQL uses backtick quoting for identifiers and LIMIT with OFFSET. SQL Server uses square bracket quoting, TOP instead of LIMIT, and CROSS APPLY instead of LATERAL JOIN. Oracle uses ROWNUM, CONNECT BY for hierarchical queries, and different date functions. BigQuery uses backtick quoting for project-qualified table names. A formatter should handle the dialect your team uses. The SQL formatter tool supports standard SQL syntax that is compatible with all major dialects. Team adoption of SQL formatting standards requires a shared configuration and ideally automated enforcement. Include SQL formatting rules in your code style guide. Use pre-commit hooks or CI checks to verify formatting on SQL files. Define the standard in a tool configuration file (like .sql-formatter.json) that is committed to the repository. The initial cost of agreeing on a standard is paid back through every code review that no longer includes formatting nitpicks and every debugging session that starts with readable code rather than a reformatting exercise. SQL in application code (embedded in Python, JavaScript, Java, or other languages) poses additional formatting challenges. A raw SQL string inside a Python function or a JavaScript template literal is subject to both the host language's formatting rules and SQL formatting rules. Multi-line string literals (Python triple-quotes, JavaScript backticks) let you maintain SQL formatting within application code. Separate the SQL string from the application logic: assign the query to a named constant (const FIND_ACTIVE_USERS = ...) and reference it where needed. For large query collections, move SQL into separate .sql files and load them at runtime. ORM-generated SQL often needs formatting for debugging. When your Django, SQLAlchemy, ActiveRecord, or Prisma query produces unexpected results, viewing the generated SQL helps diagnose the issue. Most ORMs provide a way to output the raw SQL (query.toString() in Knex, str(query) in SQLAlchemy, .explain() in Django). Paste the generated SQL into a formatter to understand its structure. ORM-generated SQL is typically dense and hard to read because it was never meant for humans. Formatted output makes the joins, conditions, and subqueries visible. Stored procedures and functions require formatting discipline beyond individual queries. Each procedure contains multiple SQL statements, variable declarations, control flow (IF/ELSE, WHILE, FOR), and exception handling (TRY/CATCH, BEGIN/EXCEPTION). Format each SQL statement within the procedure using the standard query formatting rules. Indent control flow bodies one level from their keywords. Place BEGIN and END on their own lines. Add blank lines between logical sections within the procedure. Well-formatted stored procedures are dramatically easier to debug than dense, unformatted ones. Migration files benefit from SQL formatting because they are reviewed in pull requests and represent permanent database schema changes. A CREATE TABLE statement with formatted column definitions is easy to review for correct data types, constraints, nullability, and defaults. An ALTER TABLE with multiple ADD COLUMN statements should list each column on its own line. Formatting makes migration review faster and reduces the chance of shipping a migration with incorrect column types or missing constraints. Performance analysis queries (EXPLAIN, EXPLAIN ANALYZE) produce output that is easier to correlate with the query when the query itself is formatted. If you paste a one-line query into EXPLAIN ANALYZE, the output references operations on specific query components that are hard to locate in the one-line string. The same query, properly formatted, lets you match each line of the execution plan to the corresponding clause in the query. This correlation is essential for identifying which join or subquery is causing performance problems. Dynamic SQL generation in application code should produce formatted output. When building queries programmatically (constructing SQL strings based on user input or configuration), add newlines and indentation to the generated query. This costs nothing at runtime but makes logging and debugging dramatically easier. When a generated query causes an error or performs poorly, you can read the formatted SQL in the log and immediately understand the structure. Concatenating everything into one line saves a few characters but creates debugging headaches. SQL code review checklists benefit from formatting standards. A reviewer checking formatted SQL can systematically verify: correct join types for each table relationship, WHERE clause conditions that match the business requirement, GROUP BY including all non-aggregated columns, ORDER BY reflecting the expected sort, appropriate use of LEFT JOIN versus INNER JOIN (a LEFT JOIN where INNER would suffice indicates either a bug or unnecessary caution), and absence of common anti-patterns like SELECT * in production code, implicit cross joins, and correlated subqueries that could be rewritten as joins. Formatting large legacy queries is one of the most valuable uses of a SQL formatter. Enterprise databases accumulate queries over years or decades. Queries written by developers who have long since left the company, modified multiple times, and never reformatted become walls of text that no one dares to touch. Running these queries through a formatter is the first step in making them maintainable. Format the query, commit the formatting change separately, then begin the actual modification work with a readable starting point. The SQL formatter tool takes any valid SQL query, parses its structure, and outputs consistently formatted SQL following configurable rules for indentation, keyword case, and clause placement. Paste your query, click format, and copy the result. Use it for formatting queries before committing, cleaning up legacy SQL for review, standardizing queries received from colleagues or generated by ORM tools, and preparing SQL for documentation or presentations.
Frequently asked questions
Which SQL dialects are supported?
The formatter supports standard SQL syntax including SELECT, JOIN, WHERE, GROUP BY, and other common clauses.
Does it modify my query logic?
No, the formatter only changes whitespace and casing. Your query logic remains exactly the same.
