Group by的理解

       查询选修了超过了4门课的学生和姓名。由这个来引出话题。我一开始就是这样写的:

select tb_student.Sno,Sname
from tb_student,tb_SC
where tb_Student.Sno=tb_SC.Sno
group by tb_student.Sno
having count(*)>=4;

然后就报了这样的错误:
在这里插入图片描述
后来在东南大学的一个数据库视频上面看到,自己b站由收藏。老师把这个讲清楚了。我现在记录下来,以便之后复习。

       首先我们知道,group by是用来将我们前面得到的结果集进行分组处理。那么,你的结果集就变成了一个一个组。就像我下面画的这个图一样。
在这里插入图片描述
那么现在来看,你的select子句上面就是关于这整个组的操作,上面的图是按照Sno来分组的,所以所以每一个组来说,Sno是他们的共同值,也就是说,Sno对于每一个组来说,其值是单一的。但是对于Cno来说,你要一个select Cno对于一个组而言,那么是不是就无法形成一个表格出现了。如果硬要出现,就会使这样子:
在这里插入图片描述
所以,SQL就在group by上面做了文法规定(文法,好高级。哈哈哈,应该就是语法吧),SQL在文法上要求在slelect和having上出现的属性必须是分组属性集的一个子集
为了达到这个目的,设计DBMS的开发者也是伤透了脑筋。这里老师在视频里说了,我就不提了,最后总结就是:

数据库设计的时候,程序员并不知道将来这个数据库会被用来做什么,所以,他不可能从逻辑上来检查你的select,having上出现的语句是不是分组属性的一个子集。所以,最简单的方法就是看你的select,having上出现的属性在group by上出现过。出现过,就通过编译,否则不会。

最后提一点,你之前都不知道having上的属性对于group by分组也是单一的,以后也得记得了。
最后正确答案是:

select tb_student.Sno,Sname
from tb_student,tb_SC
where tb_Student.Sno=tb_SC.Sno
group by tb_student.Sno,Sname
having count(*)>=4;
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值