SQL Formatter
What is SQL Formatting?
The SQL Formatter structures SQL queries with consistent indentation, line breaks, and clearly visible clauses. SELECT, JOIN, WHERE, GROUP BY, HAVING, ORDER BY, CTEs, and subqueries become easier to read, which helps reviews, debugging, teaching, and analysis of long reports. Formatting can also make accidental cross joins, crowded conditions, or misplaced parentheses easier to spot. It does not change database logic, optimize execution plans, guarantee dialect portability, or make unsafe dynamic SQL safe. For production changes, parameterization, permissions, indexes, transactions, locking behavior, and the actual query plan still need review in the target database.
How to Use
How to use
- Paste or enter SQL statements in the left input box
- Select indent size (2 spaces, 4 spaces, or Tab) and keyword case
- Click "Format" to beautify SQL or "Minify" to remove whitespace
- Results appear on the right with syntax highlighting
- Click "Copy" or "Download" to save results
SQL Review Notes
- Formatting improves readability but does not validate permissions, indexes, execution plans, or business correctness.
- Before running changed SQL, review generated clauses, string literals, comments, and database-specific syntax manually.
Use Cases
Technical Principle
The printing pass applies one rule per clause: SELECT / FROM / WHERE / GROUP BY / HAVING / ORDER BY / LIMIT each start a new line at column zero, projected columns and ON conditions indent one level (2 spaces, 4 spaces, or a tab), JOIN keywords (INNER / LEFT / RIGHT / FULL / CROSS) align under FROM, CASE / WHEN / THEN / ELSE / END are stacked vertically, and parenthesized subqueries and CTEs nested inside WITH receive an additional indent level so the outer SELECT remains visually anchored. String literals, line comments (-- ...), block comments (/* ... */), and dollar-quoted blocks are tokenized once and copied through unchanged so internal spacing is never touched.
Keyword casing is applied at print time, not via blind regex over the source — only tokens classified as RESERVED_KEYWORD are converted to UPPER or lower, so an identifier called 'order' or 'user' inside backticks stays in its original case. Dialect support matters because the reserved-word list differs by engine: PostgreSQL recognizes DISTINCT ON, RETURNING, ILIKE; MySQL adds IFNULL, LIMIT n,m, ENGINE=; SQL Server uses TOP n, OUTPUT, square-bracket identifiers; Oracle adds DUAL, ROWNUM, MINUS in place of EXCEPT; BigQuery and Snowflake extend the standard with QUALIFY, EXCEPT (columns), and array/struct literals. Performance is linear in source length (O(n) tokens, O(n) output bytes), so even multi-megabyte migration scripts format in milliseconds.
- Tokenizer: scans source into RESERVED_KEYWORD, IDENTIFIER, STRING_LITERAL, NUMBER, OPERATOR, LINE_COMMENT (-- ...), BLOCK_COMMENT (/* ... */), and WHITESPACE classes; comments and strings are preserved verbatim
- Dialect awareness: single-quoted strings (ANSI), backtick identifiers (MySQL), square-bracket identifiers (SQL Server), double-quoted identifiers (PostgreSQL/standard), dollar-quoted blocks $$...$$ (PostgreSQL)
- Clause layout: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT each anchor at column 0; projected columns and ON conditions indent one level; JOIN keywords align under FROM
- CTE and subquery indentation: WITH clauses indent the inner SELECT one extra level; correlated subqueries inside EXISTS / IN / scalar contexts receive their own indent so the outer query stays anchored
- Casing policy: applied at print time per token class — only RESERVED_KEYWORD tokens are upper/lowercased, so identifiers like `order` or [user] retain their original case
- Bind parameters: question-mark placeholders (MySQL prepared statements), dollar-1/dollar-2 numbered binds (PostgreSQL), and colon-name binds (Oracle/SQL*Plus) are tokenized as PARAMETER and never reformatted as identifiers
- Complexity: O(n) lexing and O(n) printing where n = source length — multi-megabyte migration scripts format in milliseconds; comparable to the sql-formatter npm library, pgFormatter, and the Prettier SQL plugin
Examples
Format a dense SELECT with JOIN and WHERE
Input: select u.id,u.name,o.total from users u left join orders o on o.user_id=u.id where u.status='active' and o.created_at>='2026-01-01' order by o.total desc limit 10;
Output:
SELECT u.id, u.name, o.total
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.status = 'active'
AND o.created_at >= '2026-01-01'
ORDER BY o.total DESC
LIMIT 10;Minify formatted SQL for a config string
Input (formatted, 6 lines):
SELECT id, name
FROM products
WHERE price < 100
AND stock > 0
ORDER BY name;
Minified output (1 line, 78 chars):
SELECT id,name FROM products WHERE price<100 AND stock>0 ORDER BY name;WITH (CTE) + nested subquery formatting
WITH recent_orders AS (
SELECT user_id, SUM(total) AS spend
FROM orders
WHERE created_at >= NOW() - INTERVAL '30 days'
GROUP BY user_id
)
SELECT u.name, r.spend
FROM users u
JOIN recent_orders r ON r.user_id = u.id
WHERE r.spend > (SELECT AVG(spend) FROM recent_orders);Lowercase keywords (team style)
Settings: Indent = 2 spaces, Keywords = lowercase
Input: SELECT * FROM Users WHERE Status=1;
Output:
select *
from users
where status = 1;
Use: matches Ruby on Rails / Django ORM-style migration filesFAQ
Which SQL dialects are supported?
Standard ANSI SQL plus common dialect-specific keywords: MySQL, PostgreSQL, MSSQL/T-SQL, SQLite, Oracle, BigQuery, Snowflake. Pick your target dialect from the dropdown so the formatter knows about dialect-specific keywords (LIMIT vs TOP, RETURNING, MERGE, etc.).
What style options are available?
Uppercase or lowercase keywords, indent size, leading vs trailing commas in column lists, max line length for wrapping, and whether to break before or after keywords. The page typically shows the options in a side panel.
Does it validate the SQL?
Most formatters parse loosely and pass questionable SQL through unchanged. Real validation needs a database connection (or at least a real SQL parser like sqlparse, sqlglot). Use this for layout; use your IDE or actual database for syntax checking.
Will it format stored procedures and triggers?
Most builds handle CREATE PROCEDURE / CREATE FUNCTION / triggers up to dialect-supported limits. Very long bodies with control flow (IF/ELSE/WHILE) format correctly; vendor extensions (T-SQL specific keywords) need the right dialect set.
Is my query uploaded?
No. Formatting runs in your browser using a JavaScript SQL parser. Pasted SQL is not transmitted. That said, never paste real production credentials or PII in any web tool.
Why are my CTEs and joins indented strangely?
Different formatters disagree on CTE alignment. Some indent each CTE definition; others keep them flush-left. Joins similarly have multiple valid styles ('JOIN x ON' vs 'JOIN x\n ON'). Pick the option that matches your team's style and stick with it.
Will it minify SQL?
Some builds offer a 'one-line' mode that strips newlines and extra whitespace. Useful for embedding SQL in code as a string literal. Always keep the formatted version in version control - one-line SQL is unreadable for review.