group by 详细用法教程

3-1 group by 详细用法教程

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

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

一、基本语法

SELECT

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

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

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

FROM

    table_name

WHERE

    condition  -- 可选过滤条件

GROUP BY

    column1, column2  -- 按这些列分组

ORDER BY

    column1;  -- 可选排序

二、核心概念

  1. 分组逻辑

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

     2. 常用聚合函数

  1. SUM():求和
  2. COUNT():计数
  3. AVG():平均值
  4. MAX():最大值
  5. MIN():最小值
  6. 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;  -- 对分组后的结果进行过滤

关键区别
  1. WHERE:过滤行数据(在分组前执行)
  2. 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

九、注意事项

  1. 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;

  1. 非聚合列未包含在 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,你可以高效地对数据进行分组和聚合,提取有价值的统计信息。合理使用聚合函数和过滤条件,能让你的查询更加灵活和强大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值