跳到主要内容

SQL 速查:6 类常用语句加按场景查表与常见坑

SELECT、WHERE、JOIN、GROUP BY、ORDER BY 和聚合函数的 SQL 语句速查,配子查询写法、按业务场景找语句的思路,以及 NULL、LEFT JOIN 降级这些真烧钱的坑。

发布于 作者 李雷
#SQL #速查 #后端 #数据分析

SQL 速查:6 类常用语句加按场景查表与常见坑

写 SQL 这事,记住语法不难,难的是在某个具体场景下立刻想起该用哪条语句,以及避开那些不报错却返回错数据的坑。这篇按"6 类常用语句、子查询、按场景查、常见坑"的顺序整理,配合 SQL 速查表 一起看,把脑子里模糊的印象固定成能直接抄的写法。

六类常用语句先理清骨架

一条查询从外往里读,骨架就这几块:

  • SELECT 选列,SELECT name, ageSELECT * 省带宽也少踩坑。
  • WHERE 过滤行,写在聚合之前。
  • JOIN 把多张表连起来,INNER 只留两边都有的,LEFT 保留左表全部。
  • GROUP BY 按列分组,配聚合函数用。
  • ORDER BY 排序,默认升序,加 DESC 降序。
  • 聚合函数 COUNT、SUM、AVG、MIN、MAX,把多行压成一个值。

顺序也是固定的:WHERE 在 GROUP BY 前,分组后再过滤要用 HAVING,最后 ORDER BY。记住这个先后,复杂查询拆开看就不慌。

一个真实例子串起来

假设有张 users 表,要找出所有成年用户的名字:

SELECT name FROM users WHERE age > 18;

再进一步,按城市统计成年用户数,只看人数超过 100 的城市,按人数从多到少排:

SELECT city, COUNT(*) AS cnt
FROM users
WHERE age > 18
GROUP BY city
HAVING COUNT(*) > 100
ORDER BY cnt DESC;

这一条就把 WHERE、GROUP BY、聚合、HAVING、ORDER BY 全用上了。注意人数过滤写在 HAVING 不是 WHERE,因为 COUNT 是分组之后才算出来的。

子查询和 CTE 让嵌套读得懂

需要"先算一批中间结果再查"的时候,子查询登场。判断存在性优先用 EXISTS 而不是 IN:

SELECT name FROM users u
WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);

嵌套超过两层就改 CTE,用 WITH 把中间步骤起个名字,读起来像一步步推导:

WITH paid AS (
  SELECT user_id, SUM(amount) AS total
  FROM orders WHERE status = 'paid'
  GROUP BY user_id
)
SELECT u.name, p.total
FROM users u JOIN paid p ON p.user_id = u.id;

按场景查比按语法背更管用

平时不是从语法出发,而是从需求出发。几个高频场景:

  • 要每组前 N 名,别堆自连接,用窗口函数 ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) 包进 CTE 再筛 rn <= 3,一遍扫描搞定。
  • 要幂等写入,Postgres 用 INSERT ... ON CONFLICT (id) DO UPDATE SET col = EXCLUDED.col,MySQL 用 ON DUPLICATE KEY UPDATE
  • 要累计求和或移动平均,用 SUM(...) OVER (ORDER BY ...),不要在应用层一行行算。

在速查里直接搜场景关键词,比翻语法目录快得多。我自己改一份老报表时,搜 LEFT JOIN 读那行坑提示,30 秒就定位了少返行的原因,比一行行盯 SQL 强太多。

那几个真烧钱的常见坑

不报错但返回错数据的坑,才是真正花钱的:

  • WHERE col = NULL 永远为假,找空值得用 IS NULL
  • 对可能为 NULL 的列写 NOT IN (子查询),子查询里有一个 NULL 整个结果就空了,改用 NOT EXISTS
  • LEFT JOIN 把右表过滤条件写进 WHERE,会偷偷降级成 INNER JOIN,要挪进 ON。
  • DELETEUPDATE 忘带 WHERE,整张表遭殃,先敲 WHERE 或包进事务看清影响行数再 COMMIT。
  • 隐式类型转换会让索引失效,给字符串却比时间戳列,索引就不走了,4 秒的查询能掉到 12 毫秒只因对齐了字面量类型。

字符串清洗里也常踩坑,复杂匹配建议先去 正则表达式速查表 把模式调对再写进 SQL 的 LIKE 或 REGEXP。

把这几类语句的骨架、按场景查的习惯和这五个坑记牢,写 SQL 的速度和准确度都会上一个台阶。


Made by Toolora · Updated 2026-06-13