You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL同表关联子查询中HAVING c2.Country <> c.Country条件作用原理求解

关联子查询运行逻辑讲解

核心执行逻辑:关联子查询逐行绑定运行

这是典型的关联子查询,执行顺序和非关联子查询完全不同,不会先计算完内层再跑外层,而是按以下步骤执行:

  1. 先执行外层的GROUP BY c.Country,得到所有国家对应的客户数临时结果,也就是你示例里的5行数据:
    cnt | Country
    3   | Argentina
    3   | Belgium
    9   | Brazil
    2   | IRAN
    2   | Turkey
    
  2. 外层逐行遍历这个临时结果,每一行都会把当前行的c.Country值代入内层子查询单独执行一次:
    • 内层先对全表Customers按c2.Country分组
    • 用HAVING c2.Country <> 外层当前传入的国家,把「当前外层行对应的国家」从内层分组结果里排除
    • 最后返回剩下所有国家的客户数集合
  3. 外层用当前行的cnt判断是否不在内层返回的集合里,符合条件就保留该行。

用示例场景逐行验证

我们拿你给出的示例数据分别验证3种典型情况:

情况1:外层当前行是巴西(cnt=9,Country=Brazil)

代入内层后c2.Country <> c.Country等价于c2.Country <> 'Brazil',内层排除巴西分组后,剩下国家的客户数是[3,3,2,2],去重后返回集合(3,2)。
判断9 NOT IN (3,2)结果为真,所以巴西行保留。

情况2:外层当前行是阿根廷(cnt=3,Country=Argentina)

代入内层后c2.Country <> 'Argentina',内层排除阿根廷分组后,剩下国家的客户数是[3,9,2,2],返回集合(3,9,2)。
判断3 NOT IN (3,9,2)结果为假,所以阿根廷行被排除。

情况3:外层当前行是伊朗(cnt=2,Country=IRAN)

代入内层后c2.Country <> 'IRAN',内层排除伊朗分组后,剩下国家的客户数是[3,3,9,2],返回集合(3,9,2)。
判断2 NOT IN (3,9,2)结果为假,所以伊朗行被排除。

逻辑本质

这段SQL的作用就是筛选出客户数是唯一值的国家:只要某国家的客户数,在其他所有国家的客户数里没有重复出现,就会被保留。

小提示:该写法是关联子查询,每一行都要跑一次内层聚合,数据量大的时候性能较差,等价的窗口函数写法性能更优:

SELECT cnt, Country 
FROM (
  SELECT COUNT(CustomerID) cnt, Country,
         COUNT(*) OVER(PARTITION BY COUNT(CustomerID)) cnt_freq
  FROM Customers
  GROUP BY Country
) t
WHERE cnt_freq = 1

内容的提问来源于stack exchange,提问作者Mohi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:27:01