欢迎访问 OceanBase 官网获取更多信息:https://www.oceanbase.com/
GROUP BY 子句用于对查询结果进行分组。
分组查询语法
GROUP BY 支持单字段分组和多字段分组,使用 WHERE 子句可以在分组前对数据进行筛选,使用 HAVING 子句可以在分组后对数据进行筛选,使用 ORDER BY 子句可以在分组后对数据进行排序。分组查询的 SQL 语句格式如下:
SELECT select_list FROM table_list
[WHERE query_condition]
GROUP BY group_by_expression
[HAVING group_condition];
select_list:
column_name, group_function,...
语法的参数说明如下:
group_function表示聚合函数。group_by_expression表示分组表达式,多个表达式之间用逗号隔开。group_condition表示分组之后对数据进行过滤。
在分组查询中,SELECT 后面的列只能是出现在GROUP BY 后面的列或者使用聚合函数的列。
分组中常用的聚合函数如下表所示。
| 聚合函数 | 作用 |
|---|---|
| MAX() | 查询指定列的最大值。 |
| MIN() | 查询指定列的最小值。 |
| COUNT() | 统计查询结果的行数。 |
| SUM() | 返回指定列的总和。 |
| AVG() | 返回指定列数据的平均值。 |
分组查询示例
创建示例表 fruit_order 并插入适当数据。
CREATE TABLE fruit_order(
order_id INT NOT NULL AUTO_INCREMENT COMMENT '订单ID',
user_id BIGINT NOT NULL COMMENT '客户ID',
user_name VARCHAR(16) NOT NULL DEFAULT '' COMMENT '客户名称',
fruit_price DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT '订单金额',
order_year SMALLINT NOT NULL COMMENT '下单年份',
PRIMARY KEY (order_id)
) COMMENT '订单表';
INSERT INTO fruit_order(order_id,user_id,user_name,fruit_price,order_year) VALUES
(1,1011,'张三',13.11,'2019'),
(4,1011,'张三',22.21,'2020'),
(6,1011,'张三',58.83,'2020'),
(2,1022,'李四',23.34,'2019'),
(3,1022,'李四',12.22,'2019'),
(7,1022,'李四',14.66,'2021'),
(8,1022,'李四',34.44,'2021'),
(5,1033,'王五',51.55,'2020'),
(9,1033,'王五',63.66,'2021');
单字段分组查询
查询每个客户下单数量,并输出客户 ID 和下单数量。
obclient> SELECT user_id 客户ID, COUNT(order_id) 下单数量 FROM fruit_order GROUP BY user_id;
+----------+--------------+
| 客户ID | 下单数量 |
+----------+--------------+
| 1011 | 3 |
| 1022 | 4 |
| 1033 | 2 |
+----------+--------------+
3 rows in set
多字段分组查询
查询每个客户每年下单数量,并输出客户 ID 、下单年份和下单数量。
obclient> SELECT user_id 客户ID, order_year 下单年份, COUNT(order_id) 下单数量 FROM fruit_order GROUP BY user_id,order_year;
+----------+--------------+--------------+
| 客户ID | 下单年份 | 下单数量 |
+----------+--------------+--------------+
| 1011 | 2019 | 1 |
| 1011 | 2020 | 2 |
| 1022 | 2019 | 2 |
| 1022 | 2021 | 2 |
| 1033 | 2020 | 1 |
| 1033 | 2021 | 1 |
+----------+--------------+--------------+
6 rows in set
分组前筛选
查询 2020 年每个客户的下单数量,并输出客户 ID 和下单数量。
obclient> SELECT user_id 客户ID, COUNT(order_id) 下单数量 FROM fruit_order t WHERE t.order_year = 2020 GROUP BY user_id;
+----------+--------------+
| 客户ID | 下单数量 |
+----------+--------------+
| 1011 | 2 |
| 1033 | 1 |
+----------+--------------+
2 rows in set
分组后筛选
查询 2019 年订单数量大于 1 的客户,并输出客户 ID 和下单数量。
obclient> SELECT user_id 客户ID, COUNT(order_id) 下单数量 FROM fruit_order t WHERE t.order_year = 2019 GROUP BY user_id HAVING COUNT(order_id)>=2;
+----------+--------------+
| 客户ID | 下单数量 |
+----------+--------------+
| 1022 | 2 |
+----------+--------------+
1 row in set
等价于:
obclient> SELECT user_id 客户ID, COUNT(order_id) 下单数量 FROM fruit_order t WHERE t.order_year = 2019 GROUP BY user_id HAVING 下单数量>=2;
+----------+--------------+
| 客户ID | 下单数量 |
+----------+--------------+
| 1022 | 2 |
+----------+--------------+
1 row in set
说明
当查询中包含 HAVING 时,先获得不含 HAVING 子句时的 SQL 查询结果,然后在这个结果的基础上使用 HAVING 条件筛选出符合的数据,最后返回这些数据。由此,HAVING 后是可以使用聚合函数,并且这个聚集函数不必与 SELECT 后面的聚集函数相同。
分组后排序
查询每个客户订单的最大金额,然后按照最大金额倒序输出客户 ID 和最大金额。
obclient> SELECT user_id 客户ID, MAX(fruit_price) 最大金额 FROM fruit_order t GROUP BY user_id ORDER BY 最大金额 DESC;
+----------+--------------+
| 客户ID | 最大金额 |
+----------+--------------+
| 1033 | 63.66 |
| 1011 | 58.83 |
| 1022 | 34.44 |
+----------+--------------+
3 rows in set欢迎访问 OceanBase 官网获取更多信息:https://www.oceanbase.com/
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




