5 条 SQL 格式化规则,让你的查询真正易读
Source: Dev.to
我们都有过这样的经历——接手一个项目,打开存储过程,却看到一整块毫无缩进、毫无结构的 SQL,简直是一团乱麻。或者是你自己六个月前写的代码,现在连它到底在干什么都看不懂。
在多年专业编写 SQL 的经验中,我总结了五条格式化规则,让我的查询语句真正可读——对团队成员以及未来的自己都友好。
Rule #1: One clause per line
每个主要的 SQL 子句单独占一行。
Bad
SELECT u.id, u.name, u.email, o.total FROM users u JOIN orders o ON u.id = o.user_id WHERE o.created_at > '2024-01-01' AND u.active = 1 ORDER BY o.total DESC;Good
SELECT u.id, u.name, u.email, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE o.created_at > '2024-01-01'
AND u.active = 1
ORDER BY o.total DESC;立刻更易扫描。你可以立即看到涉及的表、连接条件以及过滤条件。
Rule #2: Leading commas
前置逗号让注释或添加列变得非常简单。
SELECT
u.id
, u.name
, u.email
, u.created_at
-- , u.phone (easy to toggle!)
FROM users u当你需要移除某列时,不必担心尾随逗号的问题——只需把整行注释掉即可。
Rule #3: Keep CTEs clean
CTE(WITH 子句)功能强大,但很容易变得凌乱。保持每个 CTE 为清晰、独立的块。
WITH active_users AS (
SELECT id, name, email
FROM users
WHERE active = 1
AND last_login > '2024-06-01'
),
recent_orders AS (
SELECT user_id, SUM(total) AS total_spent
FROM orders
WHERE created_at > '2024-01-01'
GROUP BY user_id
)
SELECT
au.name
, au.email
, ro.total_spent
FROM active_users au
JOIN recent_orders ro ON au.id = ro.user_id
ORDER BY ro.total_spent DESC;Rule #4: Visual hierarchy
通过对齐关键字和子句来创建清晰的视觉层次。
SELECT u.name, COUNT(*) AS order_count
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE u.country = 'US'
GROUP BY u.name
HAVING COUNT(*) > 5
ORDER BY order_count DESC;你的眼睛可以通过扫描关键字快速了解查询结构,而不必阅读每一个细节。
Rule #5: Use automated formatters
手动格式化往往不够一致,尤其在团队环境中。自动化格式化工具可以帮你实现大部分规则。
- SQLNice – 免费的在线 SQL 格式化工具。
- 内置 IDE 格式化器(DataGrip、DBeaver)。
- 如
sql-formatter或pgFormatter等 CLI 工具。
Benefits of clean SQL
- 代码审查速度 – 审查者可以更快发现问题。
- 调试 – 当每个子句单独占一行时,更容易定位问题。
- 新人入职 – 新成员可以在不需要“罗塞塔石”帮助的情况下阅读查询。
- 版本控制 – 当每个元素单独占一行时,diff 更清晰。
SQL 格式化是那种小投入却能每天带来回报的技巧。从规则 #1(每行一个子句)开始,逐步完善。
你的团队遵循哪些格式化约定?留言告诉我——我一直在寻找提升 SQL 技能的方法。