Skip to content

sql_group_by

SQL 中的 GROUP BY 语句用于将相同的数据排列成组。它几乎总是与聚合函数(如 COUNT()、SUM()、AVG()、MAX()、MIN())结合使用,以便为每个组计算指标。

GROUP BY 语句将一个或多个指定列中具有相同值的行分组为一行摘要。对于每个组,您可以应用聚合函数来计算汇总统计信息。

一个关键规则是:当使用 GROUP BY 时,SELECT 列表中任何不是聚合函数一部分的列 必须 包含在 GROUP BY 子句中。这确保了结果集中的每一行都对应一个唯一的组。

SELECT column_name1, column_name2, ..., aggregate_function(column_nameX)
FROM table_name
WHERE condition
GROUP BY column_name1, column_name2, ...
ORDER BY column_name1, ...;

逻辑操作顺序:

理解逻辑处理顺序有助于编写复杂的查询:

  1. FROM(及 JOIN):指定表。
  2. WHERE:在分组前过滤单行。
  3. GROUP BY:根据指定列分组行。
  4. HAVING:过滤由 GROUP BY 创建的组(类似于 WHERE,但针对组)。
  5. SELECT:选择列并应用聚合函数。
  6. DISTINCT:从结果中移除重复行。
  7. ORDER BY:对最终结果集进行排序。
  8. LIMIT / OFFSET / TOP:限制返回的行数。

在本教程中,我们将使用受 Northwind 示例数据库启发的概念表。假设我们有“Orders”(订单)、“Shippers”(发货人)和“Employees”(员工)表。

“Orders”表示例数据:

OrderID | CustomerID | EmployeeID | OrderDate | ShipperID
------- | ---------- | ---------- | ---------- | ---------
10248 | 90 | 5 | 1996-07-04 | 3
10249 | 81 | 6 | 1996-07-05 | 1
10250 | 34 | 4 | 1996-07-08 | 2
10251 | 84 | 3 | 1996-07-08 | 1
10252 | 76 | 4 | 1996-07-09 | 2

“Shippers”表示例数据:

ShipperID | ShipperName | Phone
--------- | ---------------- | --------------
1 | Speedy Express | (503) 555-9831
2 | United Package | (503) 555-3199
3 | Federal Shipping | (503) 555-9931

“Employees”表示例数据:

EmployeeID | LastName | FirstName
---------- | --------- | ---------
1 | Davolio | Nancy
2 | Fuller | Andrew
3 | Leverling | Janet
4 | Peacock | Margaret
5 | Buchanan | Steven
6 | Suyama | Michael

SQL GROUP BY 示例:每个发货人的订单数

Section titled “SQL GROUP BY 示例:每个发货人的订单数”

要查找每个发货人处理的订单数量,我们按 ShipperName 分组并计算 OrderID 的数量:

SELECT S.ShipperName, COUNT(O.OrderID) AS NumberOfOrders
FROM Orders AS O
INNER JOIN Shippers AS S ON O.ShipperID = S.ShipperID
GROUP BY S.ShipperName
ORDER BY NumberOfOrders DESC;

此查询连接了 Orders 和 Shippers 表,然后按发货人名称对结果进行分组,并计算每个发货人的订单数。最后,结果按计数排序。

多列 GROUP BY:每个发货人和员工的订单数

Section titled “多列 GROUP BY:每个发货人和员工的订单数”

您可以按多列分组以获得更细粒度的聚合。例如,要统计每个发货人、每个员工处理的订单数:

SELECT S.ShipperName, E.LastName AS EmployeeLastName, COUNT(O.OrderID) AS NumberOfOrders
FROM Orders AS O
INNER JOIN Shippers AS S ON O.ShipperID = S.ShipperID
INNER JOIN Employees AS E ON O.EmployeeID = E.EmployeeID
GROUP BY S.ShipperName, E.LastName
ORDER BY S.ShipperName, NumberOfOrders DESC;

这为 ShipperName 和 EmployeeLastName 的每个唯一组合创建了组。

  • 对数据进行分类并计算每个类别的汇总统计信息(例如,按区域划分的总销售额,按客户细分划分的平均订单价值)。
  • 计数列中唯一值的出现次数。
  • 为显示聚合信息的图表和报告准备数据。

要根据聚合函数的结果过滤这些组,您可以使用 HAVING 子句。