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

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

这么简单的题,于是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()聚合函数。应该是这题的最优解。

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

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值