SQL Formatter & Beautifier
Paste a messy query and get it back clean and indented — one clause per line, columns lined up, subqueries stepped in. Or hit Minify to squeeze it onto a single line. Text in quotes and your comments are never changed. Everything happens in your browser and nothing is uploaded.
What the formatter actually changes
The tool reads your query one character at a time and splits it into small pieces — words, numbers, brackets, operators, text in quotes, and comments. It then writes those same pieces back out with fresh line breaks and indenting. The pieces themselves are never edited, dropped or reordered, so the query you get back does exactly what the one you pasted did. The only optional change is the upper or lower case of reserved keywords, and that is applied to keywords alone: a name you wrapped in quotes, back ticks or square brackets keeps the case you gave it, and so does every character inside a piece of text or a comment.
A worked example
Here is a real query as it often arrives — all on one line, no spaces around the operators:
select id,name,email from users u where u.active=1 and u.plan in (select plan from plans where price>0) order by name Press Format with 2-space indent and UPPER CASE keywords and you get:
SELECT
id,
name,
email
FROM users u
WHERE u.active = 1
AND u.plan IN (
SELECT plan
FROM plans
WHERE price > 0
)
ORDER BY name
Notice three things. The three columns each got their own line because there is more than one of
them. The two tests in the WHERE are stacked, so you can read them separately. And the
subquery in the brackets stepped in one more level, with its closing bracket lined up under the line
that opened it — which is how you can tell at a glance where it starts and ends. Press
Minify on the same query and it comes back on one line instead:
SELECT id, name, email FROM users u WHERE u.active = 1 AND u.plan IN (SELECT plan FROM plans WHERE price > 0) ORDER BY name How it decides where to break a line
| Rule | What it means |
|---|---|
| Only the spaces change | Words, numbers, punctuation and brackets all come back in the same order. The tool only rewrites the blank space between them. |
| One clause per line | SELECT, FROM, JOIN, ON, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, UNION, INSERT INTO, VALUES, UPDATE, SET and DELETE FROM each start a fresh line. |
| AND and OR step in | Inside a WHERE, ON or HAVING, every AND and OR starts a new line one step further in, so you can see each test on its own. The AND in BETWEEN 1 AND 9 stays put, because it is not joining two tests. |
| Columns go one per line | If the SELECT list has more than one item, each item gets its own line one step in. A single item stays on the SELECT line. Commas inside a function call, such as COALESCE(a, b), never break. |
| Subqueries step in | A bracket that starts with SELECT or WITH opens a new step of indenting, and its closing bracket lines up with the line that opened it. Every other bracket stays where it is. |
| Statements are separated | A semicolon ends a statement. The next one starts back at the left edge after a blank line, so a file of several queries stays readable. |
Function and type names such as COUNT, COALESCE or VARCHAR
are left in whatever case you typed them, because the tool cannot know whether a word like
count is a built-in function or the name of one of your own columns. If you want them
shouting, type them that way and the formatter will keep them.
SQL clause order: what you write vs. what the database does
A query is written in one order and worked through in a completely different one. Knowing the real order explains a lot of confusing error messages, so it is worth having on hand:
| Clause | You write it | Database runs it | What it does |
|---|---|---|---|
SELECT | 1st | 6th | Picks which columns, or which calculations, come back in the answer. Names made here with AS only exist from this step onward. |
FROM | 2nd | 1st | Names the table the rows are read from. This is the first thing the database actually does. |
JOIN … ON | 3rd | 2nd | Brings in a second table and says how its rows line up with the first one. |
WHERE | 4th | 3rd | Drops single rows that fail the test. It runs before any grouping, so it cannot see a SUM or a COUNT. |
GROUP BY | 5th | 4th | Folds all the rows that share a value into one row per group, so SUM, COUNT and AVG have something to add up. |
HAVING | 6th | 5th | Drops whole groups that fail the test. Simple rule: WHERE filters rows, HAVING filters groups. |
ORDER BY | 7th | 7th | Sorts what is left. Because it runs after SELECT, it can sort by a name you invented with AS. |
LIMIT / OFFSET | 8th | 8th | Keeps only the first few rows, and can skip some first. SQL Server spells this TOP or OFFSET … FETCH. |
This is why SELECT price * qty AS total … WHERE total > 100 fails but
ORDER BY total works. WHERE runs at step 3, before SELECT
has invented the name total at step 6, so at that moment the name does not exist yet.
ORDER BY runs at step 7, after it does. It is also why a total or a count belongs in
HAVING and never in WHERE: the groups those numbers are counted from are
not built until step 4.
Which databases this works with
The formatter is deliberately dialect friendly instead of tied to one product, so MySQL, MariaDB,
PostgreSQL, SQL Server, SQLite, Oracle, Snowflake, BigQuery and Redshift queries all format fine.
All three styles of quoting a name are understood — double quotes for standard SQL, back ticks for
MySQL, square brackets for SQL Server — and they are passed straight through. Placeholders such as
?, :name, @name and $1 survive, so you can format
a query straight out of your application code. Because the tool never tries to run or judge your
SQL, a keyword or function it has never met is simply copied through rather than rejected.
When people reach for this
- A query pulled out of a log file, an ORM dump or a stack trace that arrived as one long line.
- Tidying a hand-written query before a code review, so the reviewer reads logic and not layout.
- Making a colleague’s query readable before you try to change it.
- Squeezing a query onto one line to paste into a config file, a spreadsheet cell or a JSON field.
- Finding the missing bracket or the stray comma in a query the database keeps refusing.
Privacy
The formatter runs entirely on your own device. Your SQL is read and re-spaced inside your own browser, is never sent to a server, and is not stored or logged — so it is safe to use with real table names and work queries, and it keeps working offline once the page has loaded.
Frequently asked questions
- Does formatting change what my query does?
- No. The tool only rewrites the blank space between the parts of your query, and optionally the upper or lower case of reserved keywords. SQL ignores extra spaces, tabs and line breaks completely, and unquoted names are not case sensitive in any mainstream database, so SELECT id FROM t and select ID from T are the same query. The words, numbers, brackets and punctuation always come back in the same order — the tool is built around a check that proves the list of parts before and after formatting is identical, so nothing can be quietly dropped or added.
- Which SQL databases does it work with?
- It is built to be dialect friendly rather than tied to one database, so it handles MySQL, MariaDB, PostgreSQL, SQL Server, SQLite, Oracle, Snowflake, BigQuery and Redshift queries. All three ways of quoting a name are understood: double quotes for standard SQL, PostgreSQL, Oracle and SQLite, back ticks for MySQL, and square brackets for SQL Server. Because it never tries to run or check your query, a keyword or function it has not seen before is simply passed through untouched instead of causing an error. One thing to know: it follows the standard rule that a quote inside text is doubled, so a MySQL backslash escape such as backslash-quote is read as ordinary characters.
- Why are quoted text and comments left exactly as they were?
- Because changing them would change your query, and that is the single easiest way for a formatter to break something. If a piece of text in quotes happens to contain the word select or a comma or a bracket, it is still just text that gets stored or compared, so it must survive untouched. The same goes for comments: a note that says "-- select everything" is a note, not code. The tool spots quoted text and comments first, before it looks for keywords at all, so nothing inside them is ever re-cased, split across lines, or counted as a column separator.
- What is the difference between Format and Minify?
- Format spreads your query out: one clause per line, columns one per line, subqueries stepped in, so a human can read the shape of it at a glance. Minify does the opposite and squeezes the whole thing onto one line with single spaces, which is handy when you need to paste a query into a log line, a spreadsheet cell, a JSON field or a config file that dislikes line breaks. Minify keeps quoted text and comments intact too. The one thing it cannot flatten is a double-dash comment, because everything after it on a line is ignored by the database — so a line break is kept right after it to protect the rest of your query.
- Does it check my SQL for mistakes?
- Not really, and it does not pretend to. It never connects to a database, so it cannot know whether your tables and columns exist or whether the query would run. What it does do is point out two things it can be certain about from the text alone: a round bracket that was opened and never closed, and a piece of quoted text that is missing its closing quote. Both are common typing slips and both are shown under the boxes. Beyond that, simply seeing the query laid out one clause per line is usually enough to spot a missing comma or a condition that ended up in the wrong place.
- Is my SQL sent anywhere?
- No. The whole formatter is ordinary JavaScript that runs on your own device. Your query is read, re-spaced and shown back to you inside your own browser tab — it is never sent to a server, never stored and never logged, and there is no account or upload step. That makes it safe for work queries that mention real table names, customer data or internal systems. It also means the page keeps working with no internet connection once it has loaded, so you can format a query on a plane or behind a locked-down company network.