自学内容网 自学内容网

MySQL | GROUP BY子句使用详解

关注:CodingTechWork

引言

  在 MySQL 中,GROUP BY 子句用于将查询结果按照一个或多个列进行分组。每个分组会返回一行,通常与聚合函数(如 COUNT(), SUM(), AVG() 等)一起使用,用于汇总每个分组的数据。
  
本篇博客将深入探讨 MySQL 中 GROUP BY 的原理、常见的使用场景,并通过多个场景提供详细的代码示例,帮助大家全面理解 GROUP BY的使用。

GROUP BY 原理

  GROUP BY的核心作用是将查询结果中的数据按照指定的列进行分组。每个分组会包含原表中的一条记录,该记录代表了该组的数据。
  在 SQL 查询中,GROUP BY 通常与聚合函数配合使用,进行数据统计和汇总。聚合函数会对每个分组中的数据进行操作,返回每个分组的聚合结果。例如,使用COUNT()可以计算每个分组的行数,使用SUM()可以计算每个分组的值的和。

SELECT column_name, aggregate_function(column_name)
FROM table_name
GROUP BY column_name;

GROUP BY 语法结构

SELECT column1, aggregate_function(column2)
FROM table_name
WHERE condition
GROUP BY column1
HAVING condition;
  • column1: 用于分组的列。
  • aggregate_function(column2): 聚合函数,通常是COUNT(), SUM(), AVG(), MIN(), MAX()等。
  • WHERE: 用于过滤数据,分组前应用。
  • HAVING: 用于对分组后的数据进行过滤,通常与聚合函数一起使用。

GROUP BY 使用场景

数据汇总与统计

GROUP BY最常见的应用场景是对数据进行汇总和统计,通常与聚合函数结合使用。

分组统计

通过对某些字段进行分组,获得每个组的汇总统计。

筛选特定条件的分组

结合HAVING子句,可以筛选符合条件的分组。与 WHERE子句不同,WHERE作用于行数据,HAVING作用于分组后的数据。

场景代码示例

基本的 GROUP BY 示例

假设有一个orders表,结构如下:

CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    total_amount DECIMAL(10, 2)
);

插入数据:

INSERT INTO orders (order_id, customer_id, order_date, total_amount) VALUES
(1, 101, '2025-01-10', 250.00),
(2, 102, '2025-01-10', 150.00),
(3, 101, '2025-01-11', 300.00),
(4, 103, '2025-01-11', 400.00),
(5, 101, '2025-01-12', 200.00),
(6, 102, '2025-01-12', 350.00),
(7, 104, '2025-01-13', 500.00),
(8, 101, '2025-01-13', 450.00),
(9, 103, '2025-01-13', 600.00);

查询每个customer_id的订单数量

sql

SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id;

解释

通过GROUP BY customer_id,每个customer_id会成为一个组,COUNT(*) 会计算每个 customer_id 的订单数量。

结果

customer_idorder_count
1014
1022
1032
1041
  • 客户 101 有 4 个订单。
  • 客户 102 有 2 个订单。
  • 客户 103 有 2 个订单。
  • 客户 104 有 1 个订单。

使用 SUM() 聚合函数计算每个客户的总消费

sql

SELECT customer_id, SUM(total_amount) AS total_sales
FROM orders
GROUP BY customer_id;

解释

通过 SUM(total_amount) 聚合函数,查询每个 customer_id的总消费金额。

结果

customer_idtotal_sales
1011700.00
102500.00
1031000.00
104500.00
  • 客户 101 总销售额为 1700.00。
  • 客户 102 总销售额为 500.00。
  • 客户 103 总销售额为 1000.00。
  • 客户 104 总销售额为 500.00。

使用 HAVING 子句筛选特定条件的分组

假设我们想找出总消费大于 1000 的客户:

sql

SELECT customer_id, SUM(total_amount) AS total_spent
FROM orders
GROUP BY customer_id
HAVING total_spent > 1000;

解释

HAVING子句用于筛选分组后的数据。在这个例子中,只有那些消费总额大于 1000 的客户才会被返回。

结果

customer_idtotal_sales
1011700.00

多列分组

我们可以根据多个列进行分组,假设我们想根据customer_idorder_date统计每天每个客户的消费总额:

sql

SELECT customer_id, order_date, SUM(total_amount) AS total_spent
FROM orders
GROUP BY customer_id, order_date;

解释

通过GROUP BY customer_id, order_date,查询结果将返回每个客户每天的消费总额。

结果

customer_idorder_dateorder_count
1012025-01-101
1012025-01-111
1012025-01-121
1012025-01-131
1022025-01-101
1022025-01-121
1032025-01-111
1032025-01-131
1042025-01-131
  • 每个客户在每个日期的订单数被列出。

使用 GROUP BY 和 JOIN

customers表

假设customers如下

CREATE TABLE customers (
    customer_id INT,
    customer_name VARCHAR(100),
    region VARCHAR(50)
);

插入数据

INSERT INTO customers (customer_id, customer_name, region) VALUES
(101, 'Alice', 'North'),
(102, 'Bob', 'South'),
(103, 'Charlie', 'East'),
(104, 'David', 'South');

sql

我们可以使用 JOIN 将它们连接,并根据客户的地区(region)进行分组,统计每个地区的客户订单数量:

SELECT c.region, COUNT(o.order_id) AS order_count
FROM orders o
JOIN customers c ON o.customer_id = c.customer_id
GROUP BY c.region;

解释

我们通过 JOINorders 表和 customers 表连接,基于 customer_id 这一共同列。然后,我们根据 region 对客户所在地区进行分组,统计每个地区的订单数量。

结果

regionorder_count
North3
South3
East2

GROUP BY 和日期分组

sales 表

假设我们有一个 sales 表,记录了每日的销售数据:

CREATE TABLE sales (
    order_id INT,
    order_date DATE,
    sales_amount DECIMAL(10, 2)
);

插入数据

INSERT INTO sales (order_id, order_date, sales_amount) VALUES
(1, '2025-01-10', 250.00),
(2, '2025-01-11', 150.00),
(3, '2025-02-05', 300.00),
(4, '2025-02-15', 200.00),
(5, '2025-02-20', 400.00);

查询sql

SELECT YEAR(order_date) AS year, MONTH(order_date) AS month, SUM(sales_amount) AS total_sales
FROM sales
GROUP BY YEAR(order_date), MONTH(order_date);

解释

通过 YEAR(order_date) 和 MONTH(order_date),我们可以按年份和月份进行分组,查询每个月的总销售额。

结果

yearmonthtotal_sales
20251400.00
20252900.00

使用 GROUP BY 和 ORDER BY

在某些情况下,可能希望按某些列对分组结果进行排序。例如,按总消费额从高到低排序客户:

查询sql

SELECT customer_id, SUM(total_amount) AS total_spent
FROM orders
GROUP BY customer_id
ORDER BY total_spent DESC;

解释

我们查询每个客户的总消费金额,并按照 total_spent降序排列客户,显示最消费最多的客户。

结果

customer_idtotal_spent
1011200.00
1031000.00
102500.00
104500.00

注意事项与最佳实践

  • **聚合函数与 GROUP BY 一起使用GROUP BY通常与聚合函数一起使用。没有聚合函数的GROUP BY`会导致数据分组,但不会进行任何统计。
  • HAVINGWHERE的区别WHEREGROUP BY之前过滤数据,HAVINGGROUP BY后过滤分组数据。如果需要基于聚合条件进行过滤,应使用HAVING
  • NULL值的处理:在GROUP BY中,NULL会被视为一个单独的组。如果某列包含NULL值,则所有的NULL值将被归为一组。
  • 索引优化:在大数据量表上执行GROUP BY操作时,适当的索引可以显著提高性能。特别是当 GROUP BY的列是表的索引列时,查询效率更高。

总结

  GROUP BY是 SQL 查询中非常重要的功能,广泛用于数据汇总、统计和分组操作。通过与聚合函数的结合,能够在不同的业务场景中提供数据分析能力。在使用GROUP BY时,记住其原理、语法以及优化技巧,能够让你更加高效地处理和分析数据。


原文地址:https://blog.csdn.net/Andya_net/article/details/145129100

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!