SQL 格式化工具
即时格式化、美化和压缩 SQL 查询。支持 SELECT、INSERT、UPDATE、DELETE 等。免费在线工具,在浏览器中处理。
- 在浏览器中处理
- 数据不离开你的设备
- 免费 · 无需注册
用微信扫描以下二维码即可分享
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。
示例:中文别名和中文表名
MySQL 允许不加引号的名字使用 U+0080 到 U+FFFF 的字符(MySQL 8.4 参考手册:Schema Object Names),所以 as 用户名 这样的中文别名在 MySQL 里可以直接执行。本工具把连续的 Unicode 字母、数字、_、$ 读作一个名字,未加引号的中文名会整体保留,只有关键字改变大小写:
select name as 用户名, count(*) as 订单数 from orders group by name;
SELECT
name AS 用户名,
COUNT(*) AS 订单数
FROM orders
GROUP BY name;
在 SQLite 3.49.1(sql.js)里实测,原句和格式化后的句子都能执行,返回的行相同。表名、列名都是中文时也一样:
select 收货人, sum(实付金额) as 合计 from 订单 where 状态 = '已支付' group by 收货人 order by 合计 desc;
SELECT
收货人,
SUM(实付金额) AS 合计
FROM 订单
WHERE 状态 = '已支付'
GROUP BY 收货人
ORDER BY 合计 DESC;
用反引号(MySQL)或双引号(标准 SQL、PostgreSQL)括起来的名字同样原样保留:
select `收货人`, sum(`实付金额`) as `合计` from `订单` where `状态` = '已支付' group by `收货人` order by `合计` desc;
SELECT
`收货人`,
SUM(`实付金额`) AS `合计`
FROM `订单`
WHERE `状态` = '已支付'
GROUP BY `收货人`
ORDER BY `合计` DESC;
示例:压缩成一行写进日志
排查问题时,常要把一条多行 SQL 贴进日志检索框或配置项。“压缩”会把整条语句放到一行,并删掉 -- 和 /* */ 注释:-- 注释会吞掉同一行后面的所有内容,如果留在一行里,后面的条件会一起被当成注释。# 注释和不带空格的 --x 在别的数据库里是代码,所以会保留,并在其后换行。MySQL 的可执行注释 /*! … */ 和优化器提示 /*+ … */ 也是代码,格式化和压缩都原样保留。
select id, `收货人` from `订单`
where `状态` = '待发货' -- 每日对账
and created_at >= '2026-10-01';
SELECT id, `收货人` FROM `订单` WHERE `状态` = '待发货' AND created_at >= '2026-10-01';
引号里的中文和日期字符串保持原样。关键字的大小写与格式化一样,跟随“关键字大写”选项。
子查询示例
以下是默认选项(2 空格缩进、关键字大写)的实际输出。括号里的子查询会多缩进一级:
select * from users where id in (select user_id from orders where total > 100);
SELECT
*
FROM users
WHERE id IN (
SELECT
user_id
FROM orders
WHERE total > 100
);
CTE 示例
WITH ... AS (...) 的主体按子查询缩进。SUM(total) 这样的函数调用保持在一行,ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) 这样的窗口函数也一样:
with recent as (select user_id, sum(total) as spent from orders group by user_id) select u.name, r.spent from users u join recent r on r.user_id = u.id order by r.spent desc;
WITH recent AS (
SELECT
user_id,
SUM(total) AS spent
FROM orders
GROUP BY user_id
)
SELECT
u.name,
r.spent
FROM users u
JOIN recent r ON r.user_id = u.id
ORDER BY r.spent DESC;
限制
- 只有一种通用方言,不做语法校验。 没有 MySQL、PostgreSQL、SQL Server 等模式,错误的 SQL 也会照样格式化,不报错。
- 字符串里的反斜杠按两种读法之一处理。 MySQL 在未开启
NO_BACKSLASH_ESCAPES时把字符串里的\'当作转义的单引号(MySQL 8.4 String Literals);PostgreSQL 在默认的standard_conforming_strings = on下(PostgreSQL: Lexical Structure)和 SQLite(SQLite: Literal Values)把反斜杠当普通字符。本工具先按 MySQL 读法读;所有字符串都能闭合就用它,否则改用标准读法。select * from users where note = 'It\'s'压缩后仍是SELECT * FROM users WHERE note = 'It\'s',单独的'C:\'也仍是一个字符串。字符串内容总是原样复制,读法只决定字符串在哪里结束。 #或--x之后到行尾的文字原样复制。 这一行剩下的部分不再格式化,PostgreSQL 的#运算符、SQL Server 的#temp表名之后的关键字保持原来的大小写,也不换行。如果这段文字里开始了跨到下一行的字符串或/* */注释(MySQL 中合法),结果可能与原文不同。CASE保持在一行,AND/OR除外。CASE WHEN ... THEN ... END不会按WHEN拆行,但其中的AND、OR会像在WHERE里一样另起一行,例如select case when a = 1 and b = 2 then 'x' else 'y' end as k from t:
SELECT
CASE WHEN a = 1
AND b = 2 THEN 'x' ELSE 'y' END AS k
FROM t
- 压缩会删掉
--和/* */注释(/*! … */、/*+ … */原样保留;#注释和不带空格的--x保留并换行),也会去掉右括号后的空格,例如SELECT COUNT(*)FROM events。
FAQ
支持哪些 SQL 方言?
只有一种通用模式,处理 SELECT、INSERT、UPDATE、DELETE、CREATE TABLE、JOIN、子查询和 CTE,没有 MySQL、PostgreSQL、SQLite、SQL Server 的切换。常见的方言写法会原样保留:反引号和 [方括号] 名称,N'...'、X'...' 与 PostgreSQL 的 E'...' 字符串,$$...$$ 美元引号字符串,以及 $1、?1、:id、@id、@@session.sql_mode 这类参数和变量。字符串里的反斜杠只在按 MySQL 读法能让每个字符串闭合时才当作转义。压缩会删掉 -- 加空格开头的注释和普通 /* */ 注释,保留 MySQL 的 /*! */ 可执行注释和 /*+ */ 优化器提示;# 注释(MySQL)和不带空格的 --x 在不同数据库里读法不同,会原样保留到行尾,并在那里换行。
会验证 SQL 语法吗?
不会。本工具只整理排版,不检查语法错误或表结构,写错的 SQL 也会照样格式化,不报错。
很长的 JOIN、子查询和 CTE 能格式化吗?
能。每个 JOIN 单独起一行,子查询和 WITH ... AS (...) 的主体多缩进一级,SUM(total)、ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) 这样的函数调用保持在一行。CASE 表达式保持在一行(其中的 AND / OR 会另起一行),CREATE TABLE 的列定义也保持在一行。
可以自定义格式吗?
可以。缩进可选 2 个空格、4 个空格或制表符,关键字可选大写或小写。输入时自动格式化会用当前选项;改了选项之后,点击“格式化”才会应用到已有的输出。
中文列名、别名需要加引号吗?
对本工具来说不需要。连续的 Unicode 字母、数字、组合符号、_ 和 $ 都按一个名字读取,用户名、订单数这样的中文名整体保留,只有 54 个英文关键字改变大小写。数据库是否接受不加引号的中文名由数据库决定:MySQL 允许 U+0080 到 U+FFFF 的字符,PostgreSQL 允许非拉丁字母。
数据会发送到服务器吗?
不会。查询在当前浏览器标签页里格式化,不会发送到服务器,也不会保存到浏览器存储。点击“格式化”或“压缩”时,页面统计会记录工具名和这个操作,不包含 SQL 内容。