创建分组
SELECT emp_no, COUNT(*) FROM salaries GROUP BY emp_no HAVING emp_no < 10020;
输出:
+--------+----------+
| emp_no | COUNT(*) |
+--------+----------+
| 10001 | 17 |
| 10002 | 6 |
| 10003 | 7 |
| 10004 | 16 |
| 10005 | 13 |
| 10006 | 12 |
| 10007 | 14 |
| 10008 | 3 |
| 10009 | 18 |
| 10010 | 6 |
| 10011 | 7 |
| 10012 | 10 |
| 10013 | 17 |
| 10014 | 9 |
| 10015 | 1 |
| 10016 | 5 |
| 10017 | 10 |
| 10018 | 16 |
| 10019 | 4 |
+--------+----------+
19 rows in set (0.89 sec)
这条语句的前半句表示,在工资表中查找emp_no
, 以及返回该表中的所有行。但是后半句加上了GROUP_BY emp_no
语句,代表着将按照emp_no
进行分组。所有emp_no
对应的COUNT(*)
都将合并起来,最终形成这样的输出。
使用GROUP BY
的一些重要规定:
GROUP BY
子句可以包含任意数目的列。这使得能对分组进行嵌套,可以进行更细致的操作。- 如果在
GROUP BY
子句中嵌套了分组,在计算的时候会一起计算掉。 GROUP BY
子句中列出的每个列都必须是检索列或有效的表达式。如果在SELECT
中使用表达式,则必须在GROUP BY
子句中指定相同的表达式。- 在进行分组计算时,除聚集计算语句外,
SELECT
语句中的每个列都必须在GROUP BY
子句中给出。 - 如果分组列中具有
NULL
值,则NULL
将作为一个分组返回。如果列中有多行NULL
值,它们将分为一组。 GROUP BY
子句必须出现在WHERE
子句之后,ORDER BY
子句之前。
HAVING
HAVING
关键词将对GROUP_BY
进行过滤,类似于WHERE
。
HAVING 和 WHERE的区别
WHERE
在数据分组前进行过滤,而HAVING
在数据分组后进行过滤。严格意义上讲,WHERE
没有分组的概念,它无法和分组混用。
分组和排列
ORDER BY | GROUP BY |
---|---|
排序产生的输出 | 分组行,但输出可能不是分组的顺序 |
任意列都可以使用 | 只可能使用选择列或表达式列,而且必须使用每个选择表达式 |
不一定需要 | 如果与聚集函数一起使用,则必须使用 |
分组GROUP BY
在某些情况下不一定能排序,这个时候需要结合ORDER BY
可达到排序的效果。
SELECT emp_no, SUM(salary) FROM salaries GROUP BY emp_no HAVING emp_no < 10020;
分析: 从salaries表中获取emp_no,salary列,对salary列做求和计算。如果对整个列求和那明显是不合理的,所以添加了分组,按照emp_no来分组,来计算同一个emp_no所对应的salary值之和,再进行过滤到只保留emp_no小于10020的数据。
输出:
+--------+-------------+
| emp_no | SUM(salary) |
+--------+-------------+
| 10001 | 1281612 |
| 10002 | 413127 |
| 10003 | 301212 |
| 10004 | 904196 |
| 10005 | 1134585 |
| 10006 | 606179 |
| 10007 | 991574 |
| 10008 | 147923 |
| 10009 | 1409122 |
| 10010 | 460338 |
| 10011 | 348474 |
| 10012 | 469028 |
| 10013 | 891337 |
| 10014 | 476913 |
| 10015 | 40000 |
| 10016 | 374977 |
| 10017 | 870647 |
| 10018 | 1098241 |
| 10019 | 188029 |
+--------+-------------+
19 rows in set (1.07 sec)
SELECT子句顺序
子句 | 说明 | 是否必须使用 |
---|---|---|
SELECT | 要返回的列或表达式 | 是 |
FROM | 从中检索数据的表 | 仅在从表选择数据时使用 |
WHERE | 行级过滤 | 否 |
GROUP BY | 分组说明 | 仅在按组计算聚集时使用 |
HAVING | 组级过滤 | 否 |
ORDER BY | 输出排序顺序 | 否 |
LIMIT | 要检索的行数 | 否 |