SQL查询中关于group by 子句的思考

时光怂恿深爱的人放手 提交于 2020-02-02 03:17:03

问题的提出

时间:2020/2/1
事件:复习数据库

在复习的过程中,我主要是参考中国人民大学信息学院的数据库教程。

教程是实际上课的录像,课程内容的讲解同其他教程区别不大,精髓在于课上老师提出的思考问题。

在第三章数据查询部分,课上老师提出关于group by 语句的问题。

原问题是:出现在group by 语句中的列名一定要出现在select中吗?

关于这个问题,不知道读者是否有想过,如果没想过可以借此机会,现在自主思考一下。

下面将给出问题的回答。

问题的回答

group by子句回顾

GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一组。

解释一下,想象有5门课程,每门课程都有多个学生。那么我想知道各个课程及相应的选课人数。

在数据库中有一张选课表SC(Sno,Cno,score),我想要知道课程的选课人数,我需要统计总数。做统计之前,我还要把选了同一门课程的学生放到一起。这个统计之前做的工作就是分组。

查询语句:

SEKLCT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;

解析:

该语句对查询结果按Cno的值分组,所有具有相同Cno值的元组放在一起作为一组成员,然后对每一组作用聚集函数COUNT进行统计,以得出改组的学生人数。

补充:

对查询结果分组的目的是为了细化聚集函数的作用对象。

我们知道,当没有对查询结果分组时,聚集函数作用对象就是整个查询结果,那么聚集函数执行一次就行了。但是分组后聚集函数将作用于每一组,即每一组都要执行一次聚集函数,从而得出每一个函数值。

如果分组后还要按一定条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用HAVING短语指定筛选条件。

提醒:

WHERE子句与HAVING短语的区别在于作用对象不同。

WHERE子句作用于基本表或视图,从中选择满足条件的元组

HAVING短语作用于,从中选出满足条件的

发现原问题

上述查询语句是这样的:

查询语句:

SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;

我们会发现在GROUP BY子句中的Cno,在SELECT中也出现了。

写过大量SQL分组查询的读者应该都用过,就是这么写的,能够达到想要的结果,但可能没有思考为什么。

那么,是否出现在group by 语句中的列名一定要出现在select中出现呢?

回答

从SQL语法上来讲,不一定同时出现,也就是说不同时出现并不违法语法规定,它是可以通过编译的。

当然,也是可以得到查询结果的。

从实际问题上来讲,这样的查询结果是没有意义的。就像上述例子,如果SELECT语句中删除Cno。

查询语句变为:

SELECT COUNT(Sno)
FROM SC
GROUP BY Cno;

它会输出几行数字,在本例中我们知道,每一行数字代表一个课程的选课人数,但是我们并不清楚是哪门课程对应的人数,这样就失去了或者模糊了实际问题的意义。

小结

在这个问题的解决过程中,读者可能会发现这个问题本身并没有什么实际的大用处。

但我想说的是,这个思考问题的思维值得我们学习。

一个正常的问题,大家的反应一般都相同。

但是有特色的人会自主地把一个正常的问题变得不正常,从而提出新的解决方法。这样一个思维是一个可以理解为研究的思维。

有了研究的思维就离创新更近一步了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!