两条仅子查询不同的SQL语句返回结果存在差异的原因咨询
两条SQL语句结果差异的原因分析
原始数据表
| student | class |
|---|---|
| 'A' | 'Math' |
| 'B' | 'English' |
| 'C' | 'Math' |
| 'D' | 'Biology' |
| 'E' | 'Math' |
| 'F' | 'Computer' |
| 'G' | 'Math' |
| 'H' | 'Math' |
| 'I' | 'Math' |
语句1的逻辑解析
语句1的SQL代码:
SELECT class FROM Courses WHERE ( SELECT count(*) FROM Courses AS c WHERE c.class = Courses.class ) >= 5;
这里的子查询是关联子查询:外层查询每遍历一条Courses表的记录,子查询就会统计与当前记录class值相同的所有行数。
- 当外层遍历到
class='Math'的记录时,子查询统计出Math类共有6条记录,满足>=5的条件,所以这条记录会被保留; - 当外层遍历到
English、Biology、Computer这些class时,子查询统计出的对应行数分别是1、1、1,都不满足条件,因此这些记录会被过滤。
最终返回的就是所有class='Math'的6条记录。
语句2的逻辑解析
语句2的SQL代码:
SELECT class FROM Courses WHERE ( SELECT count(*) FROM Courses AS c, Courses ) >= 5
这里的子查询是无关联的笛卡尔积查询:FROM Courses AS c, Courses相当于把Courses表和自身做交叉连接(笛卡尔积),原表有9条记录,交叉连接后会生成9*9=81条记录,count(*)的结果固定为81,显然81>=5是恒成立的。
因此外层的WHERE条件永远为真,会返回Courses表中的全部9条记录。
核心差异总结
- 语句1的子查询是关联查询,针对每条记录的class单独统计数量,只保留数量达标的class记录;
- 语句2的子查询计算的是表自连接后的总记录数,结果固定且满足条件,因此返回所有原始记录。
内容的提问来源于stack exchange,提问作者trinh lap
相关产品推荐
相关产品推荐

