数据库题:查出来既学了课程号1又学了课程号2的学生学号

查出来既学了课程号1又学了课程号2的学生学号

老师课上留的思考题,觉得挺有意思的,因为总不可能傻到写出Cno=1 and Cno=2这种傻子代码嘛,想了一下写了下面的代码:
在这里插入图片描述
大概的表结构如上图所示,目测就是要找到21号这个学生。

解决方式:
在这里插入图片描述

select a.Sno from sc as  a ,sc as b  
where a.Sno=b.Sno and a.cno=1 and b.cno=2

思路:直接给这一个表取两个名字,按两个表查,一个查课程号1,另一个查课程号2,Sno相等的学生就是所求。
然后啊,我去csdn上搜了一下,也有很多人写这道题的题解,最多的就是嵌套,先查一部分,再查一部分,像这样:
在这里插入图片描述

  1. 很显然,我这个简单多了(从学生表查姓名这种事下文就不提了,我们只关注查学号这件事),但是哦,我猛地一想,不对劲呀,为什么没人想到我这个呢,极度不自信的我接着搜,根据我搜出来的结果,应该是效率太低。效率低主要体现在查找域过大。之前看到过说from和join的区别的文章,如果表中有5条数据,from这个表两次,这样搞出来就是从5*5=25个数据中查的(两张表一起查就是一个笛卡尔集的形式)。如果换成join,以此题为例两个相同的表就是5+5=10条数据(inner,left,right都是一样的,毕竟两张表都一模一样)。
    而别人那种嵌套的写法第一次从5个人中查cno=3的人,第二次从中查cno=2的人,其实吧,效率也就那样(毕竟查询了两次),写着还麻烦,因此我绝对是很聪明的那个人,只要改成join就好了 -_-嘻嘻。

  2. 然后回想到一个知识点,关于group by 的。真的好久没用过了,看到上图那个人的代码用了,看了一下,应该是起到去重的作用,以免重复出现同一名学生的信息。害,为啥我想到去重是用DISTINCT呢。好烦,我感觉group by好没用啊,所以我又去搜了一下,groupBy和distinct区别,好叭,group by全面碾压distinct,甚至还有文章告诉我distinct是性价比最低的开销最大的函数,好叭,是我low了。我去代码实践了一下,发现如果distinct只能写在开头字段上(比如id 和name 只能写在id前面,写在name前面就会报错),这样写的意思是id和name同时重复才会被查重,如果 有个性化的需求,比如只想对name去重,id可以重复,那就乖乖的用group by就好了。

总结1和2可得:
1:能用join就用join,最好别出现笛卡尔积的状况。
2.去重能用group by就用group by,distinct太low了,不过group by的主要用途还是统计分组上

所以这道题最后简单又高效的查询语句就是join联自己查啦(我觉得去重没必要,不可能会查出来重复数据呀):

select a.Sno from sc as  a 
INNER JOIN sc as b ON a.Sno=b.Sno 
where a.cno=1 and b.cno=2
  • 25
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JJpZh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值