SQL Formatter and Minifier
Format SQL with a custom lexer: clause breaks, layered JOIN and CASE indentation, IN wrapping and safe single-line minification
'' 翻倍转义、反斜杠转义、
E'…' / N'…' / X'…' / U&'…' 前缀、跨行字符串)、反引号
`带 空格`、方括号 [标识符]、-- 与 # 行注释、/* */
块注释、@@变量、:命名参数、? 占位符,以及 <>
!= >= || :: ->> ?.
这类多字运算符都能正确切分。两处按主流方言习惯取默认:反斜杠在引号字符串里一律当转义符(MySQL 默认行为);双引号内容按字符串着色,但整段原样输出, 所以 ANSI 的双引号标识符同样不会被改坏;
# 优先识别为 MySQL 行注释。括号不配对、引号或块注释没闭合时会给出大概位置并停止输出,
不会给出改坏一半的 SQL。
About this tool
Formatting SQL is less about adding line breaks and more about knowing which characters are code and which are content. A regex that finds keywords and inserts newlines will happily break a statement containing WHERE remark LIKE '%; SELECT 1' or -- a comment that also mentions FROM. This tool performs a full lexical pass first, then touches only whitespace between code tokens; strings, comments and identifiers are left byte for byte.
Three modes
- Format: clause breaks and layered indentation, for reading long reporting SQL, writing design docs or pasting into a ticket
- Minify: collapse a statement to one line for logs, config files and scheduler arguments, or to normalize both sides before a diff. Line comments become block comments so they cannot swallow the rest of the line, or can be removed entirely
- Whitespace only: keep your line structure and fix only excess spaces and spacing around operators, the smallest change for a project that is already formatted
Formatting rules
- Top-level clauses on their own lines: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, INSERT, UPDATE, SET, VALUES and WITH. Multi-word clauses are recognized as a unit, so GROUP and BY are never split across lines
- AND, OR and XOR on separate lines: with many conditions, aligned rows make the missing parenthesis easy to spot
- Layered JOINs: INNER, LEFT, RIGHT, FULL, CROSS and NATURAL each start a line, and ON or USING conditions indent one level, so multi-table joins no longer form one long horizontal line
- CASE expanded line by line: WHEN, ELSE and END each get a line, and
ENDnever swallows the following SELECT list, a common failure in online formatters - IN lists wrap by threshold: above the threshold, six by default, each element gets a line; below it the list stays as is. Function parentheses,
OVER (...)windows and VALUES tuples are never split - Subqueries and parentheses add a level: the structure of CTEs, EXISTS and derived tables is visible from indentation alone
- Blank lines between statements, with a summary of statement count, result rows, maximum depth and input characters
What the lexer protects
- Strings: single and double quotes, doubled quotes as an escaped quote, backslash escapes, multi-line strings, and prefixed forms such as
E'',N'',X'',B''andU&''are emitted unchanged - Identifiers: backtick names with spaces, bracketed names, double-quoted identifiers and non-ASCII column names stay whole and are never cut into a keyword plus fragments
- Comments:
--and#line comments and block comments keep their position. A line comment keeps its newline and is never merged into a code line - Parameters and placeholders:
@@variables,:namedparameters and?placeholders are not treated as operators - Multi-character operators:
>=,<>,!=,||,::,->>and?.stay single symbols and never split into two that change meaning - Numbers: scientific notation, leading decimal points and hexadecimal literals each remain one token
Options
| Option | Values | Effect |
|---|---|---|
| Indent | 2, 4 or 8 spaces, or Tab | Changes only the depth prefix, not which lines break |
| Keywords | Uppercase, lowercase, unchanged | Applies only to recognized keywords and type names; column and table case is never changed |
| IN wrap threshold | 1 to 99, default 6 | Elements above the threshold go one per line; 1 means IN always wraps |
| Spaces around operators | On or off | Controls spacing around equals and comparison operators; off is tighter but harder to read |
| Leading commas | On or off | Commas at line start keep diffs clean when columns are added or removed |
| Remove comments when minifying | On or off | Off keeps line comments as block comments; on deletes them |
FAQ
- Can a semicolon inside a string end the statement? No. Only semicolons outside quotes and comments count as boundaries. The sample SQL includes
';cancelled; note'with semicolons and parentheses specifically to prove this - What if parentheses or quotes do not balance? The page reports the approximate line and character and stops instead of returning half-broken SQL. A partial result is more dangerous than an error because it looks runnable
- Can the minified statement be executed? Yes. Strings and identifiers are preserved and only whitespace changes. Line comments become block comments or are removed, since
--would otherwise consume the rest of the line - Which dialect is supported? Mostly common MySQL and PostgreSQL syntax: backticks, brackets, prefixed strings,
::casts, window functions and CTEs. Dollar quoting with$$and procedural blocks are not implemented, so stored procedures need manual review - What if a table name matches a keyword? Wrapping it in backticks or double quotes makes it an identifier. A bare name that matches a keyword and is immediately followed by an opening parenthesis is treated as a function call and not as a clause break
- Does a large SQL file stall? Formatting is a single pass and handles hundreds of thousands of characters in seconds. Statement count matters more for readability; the split view lets you inspect and copy each statement
- Is the data uploaded? No. Tokenizing, formatting, highlighting, copying and download all run in page JavaScript with no requests and no server, so offline intranet use works
- How is whitespace only different from format? Format reflows line breaks and indentation. Whitespace only keeps your line positions and just normalizes extra spaces and operator spacing, which suits a team style that only needs stray spaces removed
After formatting, tidy embedded JavaScript with the JS formatter; clean up API JSON with the JSON formatter; batch edit column lists with text replace and line operations; compare two SQL files with the text diff; test validation patterns from DDL with the regex tester.