问题的提出
时间: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;
它会输出几行数字,在本例中我们知道,每一行数字代表一个课程的选课人数,但是我们并不清楚是哪门课程对应的人数,这样就失去了或者模糊了实际问题的意义。
小结
在这个问题的解决过程中,读者可能会发现这个问题本身并没有什么实际的大用处。
但我想说的是,这个思考问题的思维值得我们学习。
一个正常的问题,大家的反应一般都相同。
但是有特色的人会自主地把一个正常的问题变得不正常,从而提出新的解决方法。这样一个思维是一个可以理解为研究的思维。
有了研究的思维就离创新更近一步了。
来源:CSDN
作者:solitude5309
链接:https://blog.csdn.net/qq_36385889/article/details/104136791