记一个简单的sql题:思维扩散

330 阅读2分钟

题目很简单:(一定会有人说治好了多年的颈椎)

这么简单的题,于是1分钟不到我们有了解法1

  • 解法1: 子查询 + not in
select distinct t.name from student t where t.name not in(select t.name from student t where t.score <= 80) 

这种写法比较容易想到,先查至少有一门课程小于80,然后not in ,就是查询所有课程都大于80。但是比较冗余,也没啥技术含量,关键这种如果数据量多效率也不好,于是我们有了解法2。

  • 解法2: 子查询 + group by + having + not in
select t.name from student t group by t.name having t.name not in(select t.name from student t where t.score <= 80)

这种写法貌似和上面那种差别不大,只是加了一个分组而已? 但是,真的是这样吗,我们发现,这种写法不需要加去重,因为已经分组了。总的来说,这种写法略优于解法1,但还是老毛病,子查询需要查询2次,效率不高,于是,我们有了解法3.

  • 解法3:group by + having + count
select t.name from student t group by t.name having count(t.score) = sum(case when t.score > 80 then 1 else 0 end)

咳咳,这种写法就比较炫技了,又是分组又是聚合函数的。但是也是一种思路嘛,至于效率的话,和第二种半斤八两,只能说,这个逼装的挺6。难道没有一种不需要子查询的么? 让我们看看解法4.

  • 解法4: group by + having + min
select t.name from student t group by t.name having min(t.score) > 80

高手过招,一招制敌。用这句话形容解法4再合适不过了,抓住了题目的关键点,合理的使用min()聚合函数。应该是这题的最优解。

以上就是我对这道题的思考,如果大家还有什么其他的解法,见解, 或者我的解法有不足之处,欢迎评论区留言讨论。