第6章 子查询与集合运算:查询套查询


第6章 · 子查询与集合运算

本章要回答的三个问题:一个查询的结果怎么喂给另一个查询——子查询能落在哪几个位置、各自要求返回什么形状?IN 和 EXISTS 都能判断"在不在集合里",什么时候该用哪个、NOT IN 为什么会整体翻车?想把两张表的结果上下拼接、或取交集差集,UNION 家族怎么用才不出错?本章解决"一个 SELECT 说不完"的问题。

为什么会有这一章

第 4 章末尾留过一个悬案:AVG(SUM(price)) 这种"聚合的聚合"无法直接写——想算"各分类销售额的平均值",必须先分组算出每组 SUM,再对这组结果求平均。"对查询的结果再做查询"这个朴素愿望,就是子查询存在的全部理由。更进一步,业务还常问"买过 A 又买过 B 的顾客""价格高于全店平均的书",这些问题的条件本身就是另一个查询的答案。

子查询是通往高级 SQL 的必经之路,但也是可读性崩塌的开始——嵌套到第四层的查询没人敢改。所以本章在教写法的同时反复预告第 8 章:CTE 是给子查询起名字的脚手架,学完本章你会更懂得它为什么被发明。集合运算(UNION 家族)则从另一个维度扩展查询:JOIN 是横向拼列,UNION 是纵向拼行,一横一纵凑齐了组合结果集的完整工具箱。

读完能解决什么

  • 说出子查询的四个落点(SELECT 列、FROM、WHERE、HAVING)对返回形状的要求:标量、单行、单列、多行多列;
  • 区分相关子查询与非相关子查询的执行差异,理解为什么前者可能慢一个量级;
  • 在 IN 与 EXISTS 之间按"外表大还是子查询结果大"做选型,并解释 NOT IN 遇 NULL 翻车的机制;
  • 用 UNION 与 UNION ALL 拼接结果,说出两者在去重与性能上的差别;
  • 用 INTERSECT、EXCEPT 表达交集与差集语义(MySQL 下会写等价改写)。

各节怎么分工

节 回答哪个问题 关键产出
6.1 子查询的四个落点 查询怎么套查询 形状规则表、派生表、相关子查询机制
6.2 IN 与 EXISTS 在不在集合怎么判断 两写法对照、NOT IN 的 NULL 陷阱与三种修法
6.3 UNION 家族 结果怎么上下拼 UNION 与 UNION ALL、交集差集及 MySQL 改写

先决条件

  • 第 3 章 NULL 三值逻辑(NOT IN 陷阱的每一根引线都来自这里);
  • 第 5 章 JOIN 与反连接套路(EXISTS 本质是相关子查询版的反连接思想)。

本章知识点清单

  • 能写出标量子查询落在 SELECT 与 WHERE 中的示例,并说明对"恰好一列一行"的形状要求;
  • 能把子查询放在 FROM 里当派生表用,并解释必须起别名的原因;
  • 能识别相关子查询(内层引用外层列)并描述其逐行执行的机制;
  • 能用"聚合的聚合"案例(先分组求和再求平均)写出嵌套子查询;
  • 能判断给定两张表的大小关系下 IN 与 EXISTS 谁更合适;
  • 能手工推演 NOT IN 子查询含 NULL 时的三值逻辑结果;
  • 能写出 UNION 与 UNION ALL 的对比示例并说明排序去重的代价;
  • 能把"买过 A 又买过 B"翻译成 INTERSECT 语义。

本章概念全景

子查询教你会写复杂查询,也让你亲身体会复杂查询的痛——这份痛感是第 8 章 CTE 的最佳广告。

往下走到哪

子查询能套,但套三层就该收手了。第 7 章先介绍另一种"不折叠行"的聚合武器——窗口函数,它解决的是子查询解决得很别扭的排名、组内比较问题;第 8 章再给出给复杂查询搭脚手架的正解:CTE 与视图。

作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U