HandyTools Hub
← Back to Tools

SQL Formatter

Beautify and minify SQL queries with customizable keyword case and indentation options.

Formatted SQL will appear here...

SQL that arrives on one line is hard to review, and a WHERE clause buried at the end of it is easy to miss. This formatter takes a pasted query and lays the main clauses out on separate indented lines, with a choice of keyword casing and two-space or four-space indentation. It also has a Minify mode for the opposite job: squeezing SQL down to a single compact line for logs, URLs, or config files.

How to Use

  1. Paste or type your query into the input pane. The tool formats as you type, and the output updates live.
  2. Click Format to lay the query out, or Minify to collapse it.
  3. Choose a keyword case — uppercase, lowercase, or capitalize — from the first dropdown.
  4. Choose a two-space or four-space indent width from the second.
  5. Read the character counts under the panes to see how much the transformation added or removed, then click Copy to take the result.

In the editor, Ctrl+Enter (or Cmd+Enter) re-runs Format.

What Changes, Token by Token

The formatter works on tokens, not on a parsed syntax tree. It first lifts string literals and comments out of the way, then normalizes spacing around commas and parentheses — a comma becomes comma-plus-space, a space is forced before an opening parenthesis, and spaces inside parentheses are removed. The result is split on whitespace.

Then it walks the token list. When it sees a token whose uppercase form is a main clause and the current line is not already empty, it emits a newline and starts the next line with the configured indent. Recognized keywords are recased according to your setting, and everything else is copied through.

The practical effect is a flat, one-clause-per-line layout. A four-clause query becomes four indented lines, with each AND and OR condition on a line of its own at the same depth.

Worked Example: A One-Line Query

Input as typed:

select id, name from users where status = 'active' and age > 18 order by name asc

Output from Format with uppercase keywords and a two-space indent:

SELECT id, name
FROM users
WHERE status = 'active'
AND age > 18
ORDER BY name ASC

Notice that the string literal 'active' is untouched, the column list stays on the SELECT line, and ASC is recased because it is in the keyword list. The same input through Minify becomes:

select id, name from users where status = 'active' and age > 18 order by name asc

Minify does not recase keywords, so the lowercase spelling survives.

Now consider a query with a subquery:

select name from users where id in (select user_id from orders where total > 100)

Format produces:

SELECT name
FROM users
WHERE id IN (select user_id
FROM orders
WHERE total > 100)

Two things are worth noticing. The inner SELECT is not recased to SELECT — and does not start its own line — because the opening parenthesis glues to the keyword and the resulting token is (select, which matches neither the clause list nor the keyword list. Once the inner FROM and WHERE appear as standalone tokens, they are recognized and do start new lines, and the closing parenthesis stays attached to the final 100. It is functionally correct and far more readable than one long line, but it is not the staircase indentation a human would write by hand. That is the flat, token-based model in action.

Format Versus Minify

BehaviorFormatMinify
Line breaks at clausesYesNo
Keyword recasingYesNo
Strips commentsNoYes
Collapses whitespacePartiallyFully
Best forCode review, docs, debuggingLogs, URLs, embedded strings

A typical use is to format before reviewing and minify before embedding. Because Minify removes comments, never run it on a query whose comments carry information you need later.

How Strings and Comments Are Protected

This is the feature that keeps the tool safe to use. Before any tokenizing, every single-quoted string is replaced by a placeholder such as __STR0__, block comments by __BC0__, and line comments by __LC0__. The placeholders are inert words that cannot be mistaken for keywords, so a literal like 'Drop it' is never recased or line-broken. After formatting, the originals are restored in order.

Minify removes the comment placeholders entirely and restores the strings. One caveat: the protection matches any run between two single quotes, so dialects that escape quotes in unusual ways — doubled quotes inside a literal or backslash escapes — can confuse the boundary and are worth spot-checking.

Limitations of a Token-Based Formatter

  • Keyword matching is textual. A column named count or a table alias that collides with a keyword will be recased, and an identifier named order or set may be pushed onto a new line. Quoting such identifiers usually avoids the confusion.
  • No nesting depth. Subqueries and parenthesized expressions all sit at one indent level.
  • No syntax validation. Malformed SQL is formatted as faithfully as valid SQL; the tool does not tell you the query is wrong.
  • No dialect-specific rules. While it handles common MySQL, PostgreSQL, and SQLite syntax, it does not know about dialect-specific keywords such as RETURNING or LATERAL.
  • Comments are not reflowed. In Format mode a long inline comment stays attached wherever it happened to sit.

Frequently Asked Questions

Which keywords trigger a new line in the formatted output?

A fixed set of main clauses does: SELECT, FROM, WHERE, INSERT, INTO, VALUES, UPDATE, SET, DELETE, CREATE, ALTER, DROP, ORDER, GROUP, HAVING, LIMIT, UNION, JOIN, LEFT, RIGHT, INNER, OUTER, CROSS, FULL, ON, AND, OR, BEGIN, COMMIT, and ROLLBACK. Every one of those starts on its own line at a single indent level.

What is the difference between the uppercase, lowercase, and capitalize options?

Uppercase renders keywords as SELECT, lowercase as select, and capitalize as Select — first letter capitalized, the rest lowercased. Only words in the tool's keyword list are recased; table names, column names, and other identifiers keep whatever case you typed.

Does Minify keep my comments?

No. Minify strips both single-line comments that start with two dashes and block comments between slash-asterisk pairs, then collapses all runs of whitespace to a single space. Format mode preserves comments exactly as written.

Why does AND start a new line instead of staying next to WHERE?

AND and OR are in the newline clause list, so each condition gets its own line. It is predictable but flat: there is no hanging indent that visually nests the conditions under WHERE, so a long chain of ANDs reads as a list of equals rather than a tree.

Does formatting change how the query executes?

No. The formatter only moves whitespace and changes the case of recognized keywords, both of which SQL ignores. It does not reorder, rewrite, or validate anything, so the statement's meaning is unchanged.

Does it indent subqueries and parentheses?

Not by nesting depth. The formatter tracks only whether the current token starts a clause, so a SELECT inside parentheses is placed on a new line at the same indent as the outer query. Readable for short queries, but deep nesting only gets one level of indentation.

Reviewed by the HandyTools Hub team · Last updated