SQL Formatter
Last updated: 22 August 2026
Reviewed by Gavin ยท Research and drafting assisted by AI
SQL Formatter
A SQL formatter is a tool that takes raw, minified, or inconsistently styled SQL and produces a clean, consistently formatted version that is easy to read, easy to review, and easy to maintain. It is used daily by backend engineers, data analysts, database administrators, ORM authors, technical writers, and students who all need their queries to look the same regardless of who originally wrote them or what tool generated them. This particular SQL formatter supports four dialects, Standard SQL (ANSI SQL:2016), MySQL, PostgreSQL, and SQLite, and applies an opinionated style inspired by the popular sqlstyle.guide convention: keywords uppercase, one major clause per line, leading conjunctions in WHERE clauses, and aligned commas in SELECT lists.
The tool runs entirely in your browser, so your queries never leave your device. There is no account, no signup, and no rate limit. Paste a query, pick a dialect, pick a keyword case, pick an indent size, and the formatter does the rest. String literals, comments, and identifier casing are all preserved exactly as written.
How to Use the SQL Formatter
- Paste your SQL into the input field on the left. The example query is a simple
SELECTstatement you can overwrite. - Choose your dialect from the dropdown: Standard SQL, MySQL, PostgreSQL, or SQLite. The dialect determines which keywords are recognised and uppercased.
- Choose your keyword case: UPPERCASE (the most common style, recommended by sqlstyle.guide) or lowercase.
- Choose your indent size: 2 spaces (compact, popular in JavaScript and web stacks) or 4 spaces (more visible depth, popular in enterprise SQL).
- The formatted output appears instantly in the right-hand panel. Click Copy to grab it for your editor.
The output is recomputed live as you change options, so you can flip between UPPERCASE and lowercase, between 2-space and 4-space indent, and between dialects to see exactly how each choice affects the result. Use the Example button to reload the sample query and the Clear button to wipe the input.
What SQL Formatting Is
SQL formatting is the application of consistent style rules to a query so that its structure is visible at a glance. Unlike most programming languages, SQL is whitespace-insensitive at the syntax level: the database engine treats select id, name from users where active = true and SELECT id,\n name\nFROM\n users\nWHERE active = TRUE as identical queries. Formatting is purely for human readers.
A well-formatted SQL query breaks every major clause onto its own line, with consistent indentation inside subqueries. The clauses that get their own line are typically SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT (and OFFSET), UNION / INTERSECT / EXCEPT, and the join clauses JOIN ... ON / USING. Inside a SELECT list, each selected expression goes on its own line so it is easy to add or remove columns without touching the others. Inside a WHERE clause, the AND / OR operators are placed at the start of the line (a "leading operator" style) so the conjunction reads naturally and a vertical column of ANDs makes it obvious that several conditions are all required.
Keyword case is another major formatting decision. The two dominant choices are UPPERCASE for keywords (SELECT, FROM, WHERE) and lowercase for keywords (select, from, where). sqlstyle.guide recommends UPPERCASE because keywords stand out against lowercase identifiers. Indentation is the third leg of formatting: 2 spaces is compact and modern, 4 spaces is more visible and traditional. None of these choices change the meaning of the query; they change only how quickly a reader can find what they are looking for.
Worked Examples
Example 1, Simple SELECT
Input (minified, lowercase keywords):
select id, name, email from users where active = true;
Output (Standard SQL, UPPERCASE, 2-space indent):
SELECT
id,
name,
email
FROM users
WHERE active = TRUE;
The keywords light up, the SELECT list expands with each column on its own line, and the WHERE predicate stays on one line because it contains no top-level AND or OR.
Example 2, JOIN with WHERE
Input:
select u.id, u.name, count(o.id) as order_count from users u left join orders o on o.user_id = u.id where u.active = true and u.created_at > '2026-01-01' group by u.id, u.name order by order_count desc;
Output:
SELECT
u.id,
u.name,
COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o
ON o.user_id = u.id
WHERE
u.active = TRUE
AND u.created_at > '2026-01-01'
GROUP BY u.id, u.name
ORDER BY order_count DESC;
Notice how the LEFT JOIN's ON clause is indented one level further than the JOIN keyword, making it visually clear that the predicate belongs to the join, not to a separate WHERE. The two AND-joined conditions in the WHERE each get their own line, with the AND leading, so reviewers can scan the conditions vertically.
Example 3, CTE with multiple clauses
Input:
with active_users as (select id, name from users where active = true), recent_orders as (select user_id, count(*) as order_count from orders where created_at > now() - interval '30 days' group by user_id) select au.name, coalesce(ro.order_count, 0) as recent_orders from active_users au left join recent_orders ro on ro.user_id = au.id order by recent_orders desc;
Output:
WITH
active_users AS (
SELECT
id,
name
FROM users
WHERE active = TRUE
),
recent_orders AS (
SELECT
user_id,
COUNT(*) AS order_count
FROM orders
WHERE created_at > NOW() - INTERVAL '30 days'
GROUP BY user_id
)
SELECT
au.name,
COALESCE(ro.order_count, 0) AS recent_orders
FROM active_users au
LEFT JOIN recent_orders ro
ON ro.user_id = au.id
ORDER BY recent_orders DESC;
Common Table Expressions (CTEs) are indented one level inside their parentheses, with each CTE separated by a comma at the start of a new line. This makes it trivial to see how many CTEs there are and to add or remove one.
Example 4, INSERT statement
Input:
insert into users (name, email, created_at) values ('Alice', 'alice@example.com', '2026-08-22'), ('Bob', 'bob@example.com', '2026-08-22') returning id, created_at;
Output:
INSERT INTO users (name, email, created_at)
VALUES
('Alice', 'alice@example.com', '2026-08-22'),
('Bob', 'bob@example.com', '2026-08-22')
RETURNING id, created_at;
String literals like 'Alice' and 'alice@example.com' are preserved verbatim, which is critical: any whitespace mangling inside a quoted string would corrupt the data.
Example 5, Complex subquery
Input:
select d.department_name, e.avg_salary from (select department_id, avg(salary) as avg_salary from employees where hire_date > '2024-01-01' group by department_id having avg(salary) > 50000) e join departments d on d.id = e.department_id where e.avg_salary < 100000 order by e.avg_salary desc;
Output:
SELECT
d.department_name,
e.avg_salary
FROM (
SELECT
department_id,
AVG(salary) AS avg_salary
FROM employees
WHERE hire_date > '2024-01-01'
GROUP BY department_id
HAVING AVG(salary) > 50000
) e
JOIN departments d
ON d.id = e.department_id
WHERE e.avg_salary < 100000
ORDER BY e.avg_salary DESC;
The subquery in the FROM clause is indented one level inside its parentheses, and its closing ) e (the alias) drops back to the outer indent level so the outer SELECT, JOIN, WHERE, and ORDER BY clauses remain visually aligned with each other.
Where It Shows Up
SQL formatting shows up everywhere SQL is written or read. The most common situations are:
- Code review. A pull request with minified or inconsistently formatted SQL wastes reviewer time and slows approval. Running the formatter before opening the PR lets reviewers focus on logic instead of nitpicking whitespace.
- Schema migrations. Migration scripts like Flyway, Liquibase, Alembic, Knex, and Rails ActiveRecord migrations are usually committed once and run many times. Formatting them consistently makes them auditable years later.
- ORM debugging. When an ORM like SQLAlchemy, Hibernate, Django ORM, or Prisma generates SQL, the output is often minified and hard to read. Pasting it through the formatter is the fastest way to understand what the ORM is actually sending to the database.
- Query optimisation. Before reaching for
EXPLAINorEXPLAIN ANALYZE, format the query so you can see which tables join in which order, which predicates live in WHERE versus ON, and where the GROUP BY work happens. - Documentation. README examples, internal runbooks, and database cookbooks all need formatted SQL. Inconsistent style across examples makes the docs feel untrustworthy.
- Teaching SQL. When teaching JOINs, GROUP BY, or window functions, formatted SQL on the slide or in the textbook makes the structure immediately obvious.
- Stack Overflow and forum answers. Pasting formatted SQL into a question or answer makes it far more likely that someone will read it closely and reply with a useful answer.
Common Mistakes
Mistake 1: Allowing string literals to get reformatted. A naive "uppercase everything" formatter will break any query whose string literals contain SQL keywords. The string 'SELECT' should not become 'SELECT' if it was already uppercase, and it should never be wrapped to a new line. A good formatter recognises the boundaries of single-quoted, double-quoted, dollar-quoted, and backtick-quoted strings and treats their contents as opaque.
Mistake 2: Comments losing their newlines. Line comments (-- ...) end at the next newline, and block comments (/* ... */) may span multiple lines. A formatter that strips all whitespace will collapse a multi-line block comment into a single unreadable run of words. A good formatter preserves comment internals verbatim.
Mistake 3: Ignoring dialect-specific syntax. PostgreSQL uses $$ ... $$ dollar-quoted strings for function bodies and :: for casts. MySQL uses backtick identifiers and AUTO_INCREMENT. SQLite uses AUTOINCREMENT without the underscore. A formatter that only understands Standard SQL will choke on these. This tool lets you pick the dialect so the right keywords are recognised, and its tokeniser explicitly handles dollar-quoted blocks and backticks.
Mistake 4: Trailing semicolons getting lost. Some formatters strip trailing semicolons, which breaks stored procedures and migration scripts that need them. This tool preserves the semicolon and places it on its own line so statement boundaries are visible.
Mistake 5: No control over line length. Long queries can wrap unexpectedly and make the formatted output harder to scan. The formatter here does not enforce a hard wrap, but you can add line breaks by inserting them in the input; the formatter respects them inside comments and string literals. For long SELECT lists, putting each column on its own line (which the formatter does automatically) is usually enough.
Frequently Asked Questions
Which SQL dialects are supported? The formatter supports four dialects: Standard SQL (ANSI SQL:2016), MySQL, PostgreSQL, and SQLite. Choose the dialect that matches the database you are writing queries for. The dialect controls which keywords are recognised and uppercased. If you are writing queries that must run on more than one dialect, pick "Standard SQL" for the safest baseline set.
Does the formatter preserve string literals and comments? Yes. Single-quoted strings, double-quoted strings, PostgreSQL $$ ... $$ dollar-quoted blocks, MySQL backtick identifiers, line comments (-- ...), and block comments (/* ... */) are all recognised by the tokeniser and passed through verbatim. Their contents are never uppercased, never wrapped, and never split across lines.
Will the formatter change the meaning of my SQL? No. SQL is whitespace-insensitive at the syntax level, so changing only whitespace, line breaks, and keyword case cannot change what the database does with the query. The formatter only adjusts style; the parsed SQL is identical to the input.
What keyword case should I use, UPPERCASE or lowercase? The sqlstyle.guide convention recommends UPPERCASE keywords because they stand out visually against lowercase identifiers like column and table names. Many teams use lowercase keywords to match their surrounding code style (for example, in a JavaScript project where most identifiers are lowercase). Either choice is fine; the important thing is consistency, and this tool lets you pick whichever your team prefers.
How does the dialect dropdown affect formatting? The dialect tells the formatter which keywords to recognise. PostgreSQL-only keywords like ILIKE, JSONB, and LATERAL are only uppercased when you pick the PostgreSQL dialect. MySQL-only keywords like AUTO_INCREMENT and ENGINE are only uppercased when you pick MySQL. This prevents the formatter from accidentally uppercasing a column or table name that happens to match a keyword in a different dialect.
Can I format very long SQL queries? Yes. The formatter runs entirely in your browser, so the only limit is the size of your input and your browser's memory. Queries of several thousand lines format in a fraction of a second.
Is my SQL sent to a server? No. The formatter runs entirely in your browser using JavaScript. Your queries never leave your device, which matters when you are formatting queries that contain customer data, internal table names, or other information you would rather not upload.
What is sqlstyle.guide? sqlstyle.guide is a popular, opinionated SQL style guide maintained by Simon Holywell. It recommends reserved words in UPPERCASE, snake_case identifiers, explicit AS for aliases, leading operators in WHERE clauses, and several other conventions. This formatter follows the spirit of sqlstyle.guide, particularly the UPPERCASE keyword recommendation, the leading AND/OR style, and the one-clause-per-line layout.
References
- ANSI SQL:2016, ISO/IEC 9075:2016, the international standard for the SQL language.
- sqlstyle.guide, an opinionated, widely-adopted SQL style guide by Simon Holywell, the basis for the formatting conventions used by this tool.
- PostgreSQL Documentation, official PostgreSQL manuals, including the section on identifiers, keywords, and dollar-quoted string constants.
- MySQL Reference Manual, official MySQL documentation, including the keywords list and the backtick-quoted identifier syntax.
- SQLite Documentation, official SQLite reference, including the SQL syntax understood by the SQLite query parser.
Also try these free tools: