group by 详细用法教程

group by 详细用法教程

3-1 group by 详细用法教程

在 SQL 中,GROUP BY 子句用于将查询结果按照一个或多个列进行分组,

通常与聚合函数(如 SUM、COUNT、AVG 等)结合使用,以汇总每个组的数据。

一、基本语法

SELECT

column1, -- 必须出现在GROUP BY中或使用聚合函数

column2, -- 必须出现在GROUP BY中或使用聚合函数

aggregate_function(column3) -- 聚合函数(如SUM、COUNT等)

FROM

table_name

WHERE

condition -- 可选过滤条件

GROUP BY

column1, column2 -- 按这些列分组

ORDER BY

column1; -- 可选排序

二、核心概念

分组逻辑

将表中具有相同值的行分为一组,对每组数据执行聚合操作。

2. 常用聚合函数

SUM():求和COUNT():计数AVG():平均值MAX():最大值MIN():最小值GROUP_CONCAT()(MySQL):连接分组内的值

三、示例 1:按单列分组

假设 orders 表结构:

order_id

customer_id

amount

status

1

101

200

completed

2

101

150

pending

3

102

300

completed

需求:统计每个客户的订单总数和总金额

SELECT

customer_id,

COUNT(*) AS order_count, -- 每个客户的订单数

SUM(amount) AS total_amount -- 每个客户的总金额

FROM

orders

GROUP BY

customer_id;

结果:

customer_id

order_count

total_amount

101

2

350

102

1

300

四、示例 2:按多列分组

需求:统计每个客户、每种状态的订单数

SELECT

customer_id,

status,

COUNT(*) AS order_count

FROM

orders

GROUP BY

customer_id, status; -- 先按客户分组,再按状态分组

结果:

customer_id

status

order_count

101

completed

1

101

pending

1

102

completed

1

五、示例 3:结合 WHERE 子句过滤

需求:统计金额大于 100 的订单,按客户分组

SELECT

customer_id,

COUNT(*) AS order_count,

SUM(amount) AS total_amount

FROM

orders

WHERE

amount > 100 -- 先过滤金额大于100的订单

GROUP BY

customer_id;

六、示例 4:使用 HAVING 过滤分组结果

需求:找出总订单金额超过 200 的客户

SELECT

customer_id,

SUM(amount) AS total_amount

FROM

orders

GROUP BY

customer_id

HAVING

SUM(amount) > 200; -- 对分组后的结果进行过滤

关键区别:

WHERE:过滤行数据(在分组前执行)HAVING:过滤分组结果(在分组后执行)

七、示例 5:使用聚合函数的嵌套

需求:计算每个客户的平均订单金额,并保留两位小数

SELECT

customer_id,

ROUND(AVG(amount), 2) AS avg_amount -- 计算平均值并四舍五入

FROM

orders

GROUP BY

customer_id;

八、示例 6:分组连接字符串(MySQL)假设

products 表:

category

product_name

Electronics

iPhone

Electronics

Laptop

Clothing

T-Shirt

需求:列出每个类别下的所有产品

SELECT

category,

GROUP_CONCAT(product_name SEPARATOR ', ') AS products

FROM

products

GROUP BY

category;

结果:

category

products

Electronics

iPhone, Laptop

Clothing

T-Shirt

九、注意事项

SELECT 中的列限制

非聚合列必须全部出现在 GROUP BY 中(SQL 标准要求)。

SELECT

customer_id,

status, -- 必须出现在GROUP BY中

COUNT(*)

FROM

orders

GROUP BY

customer_id; -- 错误!缺少status列

NULL 值处理

GROUP BY 会将 NULL 视为一组:

SELECT

column_with_null,

COUNT(*)

FROM

table

GROUP BY

column_with_null; -- NULL会单独成为一组

分组顺序

多列分组时,先按第一列分组,再按第二列分组,以此类推。

十、常见错误

忘记 GROUP BY

SELECT

customer_id,

SUM(amount) -- 错误!缺少GROUP BY子句

FROM

orders;

非聚合列未包含在 GROUP BY 中

SELECT

customer_id,

status, -- 未包含在GROUP BY中

SUM(amount)

FROM

orders

GROUP BY

customer_id; -- 错误!

十一、最佳实践

明确分组目的

先确定需要按哪些列分组,再选择合适的聚合函数。

使用别名提高可读性

SELECT

customer_id AS customer,

COUNT(*) AS orders

FROM

orders

GROUP BY

customer_id;

结合 ORDER BY 排序

SELECT

customer_id,

SUM(amount) AS total

FROM

orders

GROUP BY

customer_id

ORDER BY

total DESC; -- 按总金额降序排列

十二、进阶用法:ROLLUP 和 CUBE

1. ROLLUP

生成分组的小计和总计:

SELECT

customer_id,

status,

SUM(amount)

FROM

orders

GROUP BY

customer_id, status WITH ROLLUP; -- 添加汇总行

2. CUBE

生成所有可能的分组组合:

SELECT

customer_id,

status,

SUM(amount)

FROM

orders

GROUP BY

CUBE(customer_id, status); -- 生成所有组合的汇总

通过 GROUP BY,你可以高效地对数据进行分组和聚合,提取有价值的统计信息。合理使用聚合函数和过滤条件,能让你的查询更加灵活和强大。