SQL Server数据汇总:掌握GROUP BY核心用法与技巧

远山来客
远山来客
发布时间:2026-10-13 | 4人浏览过
原创

本文详细介绍了SQL Server中如何利用GROUP BY子句进行高效的数据汇总操作。内容涵盖从基础的多列分组、条件过滤,到高级的NULL值处理、表达式分组及HAVING聚合过滤,提供完整的示例代码与结果分析,解决数据报表中的常见统计难题。

GROUP BY核心概念与准备

在使用 GROUP BY 子句之前,需明确其作用机制:它会根据指定的列或表达式将数据行划分为多个组,并对每组应用聚合函数(如 SUM, COUNT, AVG 等)。在使用 AdventureWorks2012 数据库进行测试时,确保环境已正确配置并具备查询权限。

第1步:单列分组与聚合计算

最基础的汇总操作是针对单一列进行分组。例如,统计不同承运商追踪号对应的订单总额。

操作入口与动作

  1. 选择表结构:针对 Sales.SalesOrderDetail 表进行分析。
  2. 编写查询语句:使用 SELECT 指定分组列 CarrierTrackingNumber 和聚合列 SUM(LineTotal)。
  3. 执行验证:运行查询,观察返回的记录数及前几条数据的分布情况。
USE AdventureWorks2012; 
GO 

SELECT CarrierTrackingNumber 
 ,SUM(LineTotal) AS SummarizedLineTotal 
FROM AdventureWorks2012.Sales.SalesOrderDetail 
GROUP BY CarrierTrackingNumber;

执行后通常返回数千条记录。关键注意点:只有出现在 GROUP BY 子句中的非聚合列,才能出现在 SELECT 列表中。其他数值型字段必须通过聚合函数处理。

第2步:多列组合分组排序

当需要同时基于多个维度(如产品和日期)进行细分统计时,可使用多列分组。此时,SQL Server 会根据这两列组合的唯一性来划分数据组。

操作入口与动作

  1. 连接主表:关联 SalesOrderDetail 与 SalesOrderHeader 以获取产品信息和订单日期。
  2. 设置多重分组:在 GROUP BY 中依次列出 ProductID 和 OrderDate。
  3. 结果排序:使用 ORDER BY 指定按汇总金额降序排列,便于快速定位高价值记录。
SELECT D.ProductID 
 , H.OrderDate 
 , SUM(LineTotal) AS SummarizedLineTotal 
FROM AdventureWorks2012.Sales.SalesOrderDetail D 
JOIN AdventureWorks2012.Sales.SalesOrderHeader H 
ON D.SalesOrderId = H.SalesOrderID 
GROUP BY ProductID, OrderDate 
ORDER BY SummarizedLineTotal DESC;

第3步:使用HAVING子句过滤聚合结果

HAVING 子句是专为 GROUP BY 设计的过滤器。与 WHERE 在分组前过滤原始行不同,HAVING 用于过滤经过聚合计算后的组。常用于限制显示平均薪资超过某值的部门,或总销售额超过阈值的产品类别。

操作入口与动作

  1. 确定过滤目标:本例设定筛选条件为总金额大于 200,000。
  2. 应用HAVING条件:在查询末尾添加 HAVING SUM(LineTotal) > 200000。
  3. 检查输出行数:符合条件的组数量会显著减少,仅保留满足高额度标准的记录。
SELECT D.ProductID 
 , H.OrderDate 
 , SUM(LineTotal) AS SummarizedLineTotal 
FROM AdventureWorks2012.Sales.SalesOrderDetail D 
JOIN AdventureWorks2012.Sales.SalesOrderHeader H 
ON D.SalesOrderId = H.SalesOrderID 
GROUP BY ProductID, OrderDate 
HAVING SUM(LineTotal) > 200000 
ORDER BY SummarizedLineTotal DESC;

第4步:应对NULL值的特殊表现

在SQL Server中,所有 NULL 值被视为相等。因此,如果存在空值列,它们会被归入同一个分组内进行处理。

操作步骤演示

  • 测试建表:创建一个包含若干有效日期和 NULL 日期的临时表。
  • 执行聚合:GROUP BY 会将所有 NULL 行合并为一行,并对剩余有效数据独立成组。
  • 观察结果:确认输出中是否存在一行标记为 NULL 且包含所有空值记录的累加值。
CREATE TABLE NullGroupBy (OrderDate date, Amount Int);
INSERT INTO NullGroupBy values (NULL,100),
('10-30-2014',100),
('10-31-2014',100),
(NULL,100);
SELECT OrderDate, SUM(Amount) as TotalAmount
FROM NullGroupBy
GROUP BY OrderDate;
DROP TABLE NullGroupBy;

第5步:在分组中使用表达式

除了直接引用列名,还可以对日期等数据进行格式化处理后作为分组依据。这非常适用于按月或按季度进行业务趋势分析。

具体实施方法

  1. 构建表达式:使用 CONVERT(CHAR(7), OrderDate, 120) 截取年份-月份格式。
  2. 嵌入GROUP BY:确保 SELECT 中的表达式与 GROUP BY 中的完全一致。
  3. 效果验证:系统将按照 YYYY-MM 的组合维度重新划分数据集,忽略具体的天数差异。
SELECT CONVERT(CHAR(7),H.OrderDate,120) AS [YYYY-MM] 
 , SUM(LineTotal) AS SummarizedLineTotal 
FROM AdventureWorks2012.Sales.SalesOrderDetail D 
JOIN AdventureWorks2012.Sales.SalesOrderHeader H 
ON D.SalesOrderId = H.SalesOrderID 
GROUP BY CONVERT(CHAR(7),H.OrderDate,120) 
ORDER BY SummarizedLineTotal DESC;

以上就是关于SQL Server数据汇总详细的内容,更多关于SQL Server查询优化的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表