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
子句外,其他的子句全都可以省略。
一个查询中若出现多个子句,它们间顺序必须如下:
(1). SELECT [DISTINCT] 查询列表
(2). [FROM
表名]
(3). [WHERE
布尔表达式]
(4). [GROUP BY
分组列表]
(5). [HAVING
分组过滤条件]
(6). [ORDER BY
排序列表]
(7). [LIMIT
偏移量, 限制条数]