分组
分组操作的目的:就是为了统计。
分组的关键字:GROUP BY。
分组筛选:用 HAVING 进行条件筛选。
常见的分组:分组统计、分组排序、多分组统计、回溯统计、统计筛选。
分组统计:查询时在 WHERE 条件后添加 GROUP BY 即可进行分组统计。
在 MySQL5.7 中分组后,SELECT 获取的字段列表只能是 GROUP BY 分组的字段,或使用了聚合函数的非分组字段。
若在获取非分组字段时没有使用聚合函数,MySQL 会报错误提示。
通过聚合函数 MAX()获取每个分类下商品的最高价格。
mysql> SELECT categoryid, MAX(price) FROM shgoods GROUP BY category_id;
+-------------+------------+
| category_id | MAX(price) |
+-------------+------------+
| 3 | 15.00 |
| 6 | 1999.00 |
| 8 | 69.00 |
| 9 | 109.00 |
| 10 | 2000.00 |
| 12 | 5999.00 |
| 15 | 299.00 |
| 16 | 48.00 |
+-------------+------------+
8 rows in set (0.00 sec)
MySQL5.6 等老版本中,分组后获取的字段列表,若非分组字段没有使用聚合函数,默认只保留每组中的第一条记录。
但是此操作在 MySQL5.7 及以上版本中已被禁止。
为避免项目开发 MySQL 版本升级带来的问题,推荐读者在编写分组 SQL 语句时按照 MySQL5.7 新版本更严格的方式进行设计。
分组排序:默认分组操作的字段提供按升序排序,因此在分组时可为指定的字段进行升序或降序排序。
SELECT [select 选项] 字段列表 FROM 数据表名
[WHERE 条件表达式] GROUP BY 字段名 [ASC | DESC];
GROUP BY 分组排序的实现不需要使用 ORDER BY,直接在分组字段后添加 ASC(升序,默认值可省略)或 DESC(降序)即可。
根据 sh_goods 表中的分类 id 进行分组降序操作
mysql> SELECT categoryid, GROUPCONCAT(id), GROUP_CONCAT(name)
-> FROM shgoods GROUP BY categoryid DESC;
+-------------+------------------+--------------------+
| categoryid | GROUPCONCAT(id) | GROUP_CONCAT(name) |
+-------------+------------------+--------------------+
| 16 | 10 | |
| 15 | 9 | |
| 12 | 4 | |
| 10 | 8 | |
| 9 | 7 | |
| 8 | 6 | |
| 6 | 5 | |
| 3 | 1,2,3 | |
+-------------+------------------+--------------------+
8 rows in set (0.00 sec)
多分组统计:按某个字段进行分组后,对已经分组的数据进行再次分组的操作。
SELECT [select 选项] 字段列表 FROM 数据表名
[WHERE 条件表达式]
GROUP BY 字段名 1 [ASC | DESC], [, 字段名 2 [ASC | DESC]]…;
查询出的数据首先按照字段 1 进行分组排序,再将字段 1 相同的结果按照字段 2 进行分组排序,依次类推。
以评分 score 降序分组后,再以评论数 comment_count 升序排序
mysql> SELECT score, COUNT(*), GROUPCONCAT(name), commentcount
-> FROM shgoods GROUP BY score DESC, commentcount;
+-------+----------+--------------------+---------------+
| score | COUNT(*) | GROUPCONCAT(name) | commentcount |
+-------+----------+--------------------+---------------+
| 5.00 | 2 | | 98000 |
| 4.90 | 2 | | 40000 |
| 4.80 | 1 | | 6000 |
| 4.80 | 1 | | 98000 |
| 4.50 | 1 | | 1000 |
| 3.90 | 2 | | 500 |
| 2.50 | 1 | | 200 |
+-------+----------+--------------------+---------------+
7 rows in set (0.00 sec)
回溯统计:在根据指定字段分组后,系统又自动对分组的字段向上进行了一次新的统计并产生一个新的统计数据,且该数据对应的分组字段值为 NULL。
SELECT [select 选项] 字段列表 FROM 数据表名
[WHERE 条件表达式]
GROUP BY 字段名 1 [ASC | DESC], [, 字段名 2 [ASC | DESC]]… WITH ROLLUP;
虽然回溯统计对数据的分析很有帮助,但是 MySQL 的同一个查询语句中回溯统计(WITH ROLLUP)与排序(ORDER BY)仅能出现一个。
版权声明: 本文为 InfoQ 作者【在即】的原创文章。
原文链接:【http://xie.infoq.cn/article/7fb6e05098efcc3c13509d5d1】。文章转载请联系作者。
评论