SQL 课程 12:查询的执行顺序

SQL 的书写顺序是 SELECT → FROM → WHERE → GROUP BY……,但数据库实际执行时会先找到数据来源、连接表、筛选行,再分组汇总,最后才选择要展示的字段。理解这个顺序,是排查复杂查询错误最快的办法。

例如,SELECT 中起的别名不能直接在 WHERE 中使用,因为 WHERE 执行得更早;而 HAVING 用于筛选聚合后的组,因为它发生在 GROUP BY 之后。

SQL 的常见逻辑执行顺序
1. FROM / JOIN      确定数据来源并连接表
2. WHERE            筛选原始记录
3. GROUP BY         形成分组
4. HAVING           筛选分组
5. SELECT           计算并选择展示字段
6. ORDER BY         排序结果
7. LIMIT / OFFSET   截取结果

把查询想成一条数据加工流水线

从 sales_pipeline 和 accounts 连接开始,每笔商机先获得客户行业;再用 WHERE 保留已成交记录;随后按行业 GROUP BY;HAVING 可以过滤商机数太少的行业;最后 SELECT 展示指标并按指标排序。

当结果“不对”时,沿着这个顺序检查:连接是否让行数膨胀?WHERE 是否过早过滤?GROUP BY 的粒度是否正确?HAVING 是否错误地写成了 WHERE?

按行业统计已成交商机并排序
SELECT a.sector,
       COUNT(*) AS won_opportunity_count
FROM sales_pipeline AS p
JOIN accounts AS a
  ON p.account = a.account
WHERE p.deal_stage = 'Won'
GROUP BY a.sector
ORDER BY won_opportunity_count DESC;

WHERE、HAVING 与别名的常见误区

WHERE close_value > 1000 是对每笔商机筛选;HAVING SUM(close_value) > 1000 是对每位销售人员的汇总金额筛选。两者看起来相似,回答的却不是同一个业务问题。

ORDER BY 在 SELECT 之后执行,因此可以使用 SELECT 中的别名,如 ORDER BY won_close_value DESC。WHERE 执行较早,不能依赖同一层 SELECT 刚起好的别名。

按执行阶段选择子句

想做什么应使用示例
只看已成交商机WHEREWHERE p.deal_stage = 'Won'
只看成交数不少于 100 的销售人员HAVINGHAVING COUNT(*) >= 100
按汇总金额从高到低展示ORDER BYORDER BY won_close_value DESC

小提醒:不要机械背顺序。每写一个条件,先问它是在筛一条原始记录,还是在筛一组汇总结果。

练习

本课没有新函数,重点是把已学子句放在正确位置。最后一题会同时验收 JOIN、筛选、分组和排序。

表格:sales_pipeline(商机)

查询返回 0 行。

显示第 00
1 / 1
正在准备浏览器内 SQL 数据库…