筛选员工超2人部门的SQL子查询如何正确实现向量化运行?
问题SQL执行逻辑说明
你所提到的查询是关联子查询(Correlated Subquery),运行逻辑完全是确定性的,不存在偶然生效的情况,原查询代码如下:
/*With subquery*/ SELECT D.Name FROM Departments D WHERE 2 < ( SELECT COUNT(*) FROM Employees WHERE Department = D.Code );
具体执行步骤拆解
- 外层查询先逐行扫描
Departments表的每一条记录(表别名设置为D),扫描到任意一行时,都会拿到当前行的Code字段值,也就是当前遍历到的部门的编号 - 外层查询把当前行的
D.Code值传入内层子查询,子查询的WHERE Department = D.Code条件会过滤Employees表,只统计属于当前这个部门的员工总数,返回COUNT(*)的数值结果 - 外层判断该数值是否大于2,如果符合条件,就保留当前
Departments行的Name字段,不符合就丢弃
样例数据实际计算过程
对应你提供的测试数据,各部门的计算结果如下:
| 部门编号 | 部门名称 | 子查询统计的员工数 | 是否满足>2 | 是否保留 |
|---|---|---|---|---|
| 14 | IT | 5 | 是 | 是 |
| 37 | Accounting | 2 | 否 | 否 |
| 59 | Human Resources | 3 | 是 | 是 |
| 77 | Research | 2 | 否 | 否 |
最终返回结果就是IT和Human Resources两个部门名称。
疑问点解答
WHERE Department = D.Code的作用:这个是关联子查询的核心关联条件,相当于给内层计数划定了范围,每次只统计当前外层正在遍历的那个部门的员工数,完全是按规则匹配,没有随机性。- 向量化执行逻辑:MSSQL不管是传统的行模式执行,还是批模式(向量化)执行,核心逻辑都是将外层的部门编号和内层员工的所属部门编号做匹配计算,只是向量化模式会批量处理多行数据提升效率,不会改变计算规则和结果。
- 结果有序性:SQL本身默认不保证返回结果的顺序,如果你需要结果按特定规则排序,需要主动在查询末尾加
ORDER BY子句,比如ORDER BY D.Name就可以按部门名称字典序返回结果,否则返回顺序由MSSQL的查询优化器决定,可能随数据量、索引情况变化。
内容的提问来源于stack exchange,提问作者J. Mini
相关产品推荐
相关产品推荐

