分组查询
上一章我们学习了一些汇总函数用于数据统计,在实际操作的时候往往情况会比较复杂,比如要查询两门课程的平均分,是不是就要写两遍avg函数呢?实际上在同一类问题的重复操作是存在改进空间的,这一张我们就学会如何进行分组查询,避免重复操作。
创建分组;
比如一个表格中课程的种类有20种,暂且我们的办法只能一个语句一个语句的查询。但这里我们可以学习一种新的方法,建立分组,进行查询。
语法:select 表达式 from 表 group by 表达式
mysql> select max(number), score from student_score group by score;
+-------------+-------+
| max(number) | score |
+-------------+-------+
| 220101103 | 78 |
| 220101102 | 79 |
| 220101105 | 77 |
+-------------+-------+
3 rows in set (0.01 sec)
mysql> select max(number), subject, score from student_score group by score;
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'zrt.student_score.subject' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
我们可以看到我们在查询的时候如果加入了subject的话系统会报错,这说明我们在进行分组查询的时候,不应该把非分组列加入到分组查询中去。因为那样会导致结果集中非分组列的值不确定。
带有where子句的分组查询:
比如我们在查询平均分的时候我们要过滤掉60分以下的分数再分学科进行查询的话我们就可以在from语句以后加个where score>=60 再group就行了。
作用于分组的过滤条件:
比如我们有时候产生了非常多的分组,而此时需要的只是一部分,我们就可以在group后面加上一个having子句,having后加上过滤条件即可。
having子句和where语句的过滤效果其实是一样的。
分组和排序:
我们在分组的时候,可以一层一层的进行细分,当分组条件比较多的时候,我们分组条件就可以在group by子句后把各个分组依次写上,然后再用逗号分隔开就好了。
但在使用分组查询的时候要注意:
1.如果分组列中含有NULL,那么NULL也会作为一个独立的分组存在。
2.group by子句后也可以跟随表达式,但不可以是汇总函数
having子句和where子句的区别:
where子句在分组前进行过滤,作用于每一条记录,不符合where条件的记录不会参与分组;而having子句在将记录分组后进行过滤,作用于整个分组。
学了这么多查询子句,自然要记住他们的查询顺序:
select [distinct] 查询列表
[from 表名]
[where 布尔表达式]
[group by 分组列表]
[having 分组过滤条件]
[order by 排序列表]
[limit 偏移量, 限制条数]