1.分组数据
_1.复杂的数据统计
如:SELECT AVG(score) FROM student_score WHERE subject = 'Mysql是怎样运行的';
上述实现查询指定课程的平均成绩。对FROM得到的结果集1,通过WHER进一步过滤得到结果集2。对结果集2中每一行执行汇总计算。
_2.创建分组
所谓分组,就是针对某个列,将该列的值相同的记录分到一个组中。
MYSQL提供了Group By子句来帮助我们自动完成分组过程:
如:SELECT subject, AVG(score) FROM student_socre GROUP BY subject;
上述语句实现方式为:
基于FROM语句得到结果集1,对结果集1结合WHERE语句进行过滤得到结果集2,对结果集2按GROUP BY语句得到多个子结果集。每个子结果集中的每一行GROUP BY中表达式的值均一致。对每个子结果集依次执行SELECT语句。每个子结果集经过SELECT处理后得到一个新的子结果集。将所有新的子结果集汇集在一起,构成最终结果集。
每个子结果集预期经过SELECT处理后新的子结果集中只有一行才可以。
_3.带有WHERE子句的分组查询
如:SELECT subject, AVG(score) FROM student_score WHERE score >= 60 GROUP BY subject;
_4.作用于分组的过滤条件
上述WHERE子句对结果集的过滤发生在分组前,如果希望对分组产生的子结果集进行过滤,使用HAVING。
不同于WHERE,WHERE用于对FROM得到的结果集1中的每一行执行条件过滤。
HAVING用于对GROUP BY产生的多个子结果集中的每个结果集执行条件过滤。
这意味着,WHERE针对每一行过滤的结果将决定参与过滤的行是否可以进入结果集2;HAVING针对每个子结果集过滤的结果将决定参与过滤的子结果集是否可进入后续执行SELECT处理的子结果集集合。
因为这些特性相应的WHERE中不可使用汇总函数来过滤,HAVING中可以(HAVING中要么用汇总函数,要么用分组列)。
_5.分组和排序
如:SELECT subject, AVG(score) AS avg_score FROM student_score WHERE score > 70 GROUP BY subject HAVING MAX(score) > 60 ORDER BY avg_score DESC;
上述语句执行顺序为:
(1).通过FROM语句得到结果集1
(2).通过WHERE语句对结果集1逐行过滤得到结果集2
(3).通过GROUP BY语句拆分结果集2得到多个子结果集构成的结果集集合1
(4).通过HAVING语句对结果集集合1中每个子结果集执行过滤得到新的多个子结果集构成的结果集集合2
(5).通过SELECT语句对结果集集合2中每个结果集执行处理得到一行记录,构成最终结果集1。
(6).通过ORDER BY子句对最终结果集1中行执行排序得到排序后的最终结果集2。
_6.多个分组列
通过GROUP BY中指定多个列,可以使得子结果集数量更多(分组分的更细了,每个分组中所有行必须满足多个分组列均一致)。
如:SELECT department, major, COUNT(*) FROM student_info GROUP BY department, major;
_7.使用分组查询其他注意事项
(1).如分组列中含NULL,则NULL将作为一个独立的分组存在。
(2).GROUP BY子句后也可跟随表达式(其实列名也属于表达式)
将结果集拆分成多个子结果集的原则就是,对结果集中每个行执行GROUP BY中表达式运算,运算结果一致的行汇集在一起构成一个拆分后的子结果集。
(3).注意,WHERE过滤发生在分组前,对象是每一行,根据过滤结果决定对应行是否加入结果集2。HAVING过滤发生在分组后,对象是子结果集。根据过滤结果决定对应子结果集是否加入结果集集合2。
2.简单查询语句中各子句顺序
除了SELECT子句外,其他的子句全都可以省略。
一个查询中若出现多个子句,它们间顺序必须如下:
SELECT [DISTINCT] 查询列表
[FROM 表名]
[WHERE 布尔表达式]
[GROUP BY 分组列表]
[HAVING 分组过滤条件]
[ORDER BY 排序列表]
[LIMIT 偏移量, 限制条数]