为何以下两条SQL查询语句返回结果不一致?
为什么两条SQL查询结果不一致?
咱们一条一条拆解问题所在:
第一条语句的核心错误
你写的第一条语句里:
count(distinct grade > 17) = 13
这里的grade > 17是一个布尔判断,在绝大多数SQL数据库里,布尔值会被转换成1(true)或者0(false)。也就是说,不管有多少种不同的合格成绩,distinct grade >17只会产生两个可能的值:1(当成绩≥18时)和0(当成绩<18时)。
所以count(distinct grade >17)的结果最多是2,永远不可能等于13——这就是为什么这条语句返回0行结果。
正确的写法应该是先筛选出合格成绩,再统计不同值的数量,比如:
select sid, name, count(distinct grade) from student natural join exam where grade >= 18 -- 先过滤合格成绩 group by sid, name having count(distinct grade) = 13;
第二条语句的逻辑(以及它为什么这次能返回结果)
第二条语句:
select sid, Name from exam natural join student group by sid having count(distinct grade) = ( select count(distinct grade) from exam );
它的逻辑是:统计每个学生的不同成绩数量,然后和整个exam表中所有不同成绩的数量做对比。
你说这条返回了1行结果,说明你的exam表中所有存在的不同成绩恰好就是那13个合格成绩(18到30)——也就是说,表中没有任何低于18分的成绩。这时候子查询select count(distinct grade) from exam的结果正好是13,所以能匹配到那个取得了所有13种成绩的学生。
但如果你的exam表中存在不合格的成绩(比如17分及以下),这条语句就会出错:它会去找那些取得了所有成绩(包括不合格)的学生,而不是只找取得所有合格成绩的学生。
总结两条语句结果不同的原因
- 第一条语句因为错误地对布尔表达式去重计数,永远不可能满足
=13的条件,所以返回0行。 - 第二条语句在你的数据场景下(exam表只有合格成绩)碰巧得到了正确结果,但逻辑上没有限定“合格成绩”的范围,只是匹配了表中所有存在的成绩。
内容的提问来源于stack exchange,提问作者Chiara
相关产品推荐
相关产品推荐

