-- 查出所有科目成绩都在50分以上的学生 +------------+---------+-------+ | student_id | subject | score | +------------+---------+-------+ | 1 | 数学 | 100 | | 1 | 语文 | 80 | | 1 | 理化 | 80 | | 2 | 数学 | 80 | | 2 | 语文 | 95 | | 3 | 数学 | 40 | | 3 | 语文 | 90 | | 3 | 社会 | 55 | | 4 | 数学 | 80 | +------------+---------+-------+ -- 直接写法 select student_id from test_scores group by student_id having sum(case when score>50 then 1 else 0 end)=count(*); -- 转化成双重否定,没有一个科目不满50分 -- 所有学生减去有低于50分的学生 select distinct student_id from test_scores as t1 where not exists ( select * from test_scores as t2 where t1.student_id=t2.student_id and t2.score<50 );
-- 找出数学成绩不低于80,语文成绩不低于50,必须同时拥有语文和数学成绩 -- 直接写法 select student_id from test_scores where 1 = case when subject = '语文' and score >= 50 then 1 when subject = '数学' and score >= 80 then 1 else 0 end group by student_id having count(*) = 2;
-- 双重否定写法,减法运算,注意subject in select student_id from test_scores as t1 where subject in ("数学", "语文") and not exists ( select * from test_scores as t2 where t1.student_id=t2.student_id and 1 = case when subject = '数学' and score < 80 then 1 when subject = '语文' and score < 50 then 1 else 0 end ) group by student_id having count(*) = 2;
having与not exists的优缺点比较 having逻辑易理解 not exists不易理解但利用到索引性能好