问题:按授课班号统计选修该课程的人数,并按照人数升序排列。
--cno是课程号,sno是学号,sc是选修课程表
select cno,COUNT(distinct sno) as 人数 from sc
group by cno
order by 人数 ASC
上面的select语句中包含了cno以及聚集函数,最后的运行结果如下图:
下面看看删去cno 改成sno的运行结果:
当select语句中出现了不在group by语句中的字段就会报错,错误信息也表示是这个错误。
个人理解,原因如下:
- group by是按照给定的属性进行分组,分组后每个组可能出现多值。
- 分组后,之后的查找都是按照分组的各个小组内进行查找,小组之间不交叉,否则出现歧义。
- 例如题目中分组后一组可能有多个选修该课程的同学,在这种情况下再使用其余属性名去访问或查找时会出现歧义,假如SQL中select的是名字,那么此时数据库是从小组中查找还是整个表中查找,为了避免这样情况出现所以group by中属性必须出现在查找中。
那么为什么可以存在聚集函数?首先得看看代码执行顺序
- 1.from子句组装来自不同数据源的数据;
2.where子句基于指定的条件对记录行进行筛选;
3.group by子句将数据划分为多个分组;
4.使用聚集函数进行计算;
5.使用having子句筛选分组;
6.计算所有的表达式;
7.使用order by对结果集进行排序;
8.select 集合输出。 - 可以看出,聚集函数是在group by之后执行的,所以having会在各个分组中进行执行,小组之间不会交叉,不会出现有歧义的情况。
以上是个人理解,如有错误欢迎指出!