如何在GROUP BY子句中忽略描述差异实现分组统计?
解决方案:忽略描述差异分组并保留任意描述值
你的需求我太懂了——就是因为描述字段录入不规范,导致同一个零件同一年的记录被拆成了好几组,现在要合并起来求和,同时随便返回一个描述就行对吧?下面针对不同主流数据库给你具体实现方案:
1. MySQL 实现
MySQL 自带的 ANY_VALUE() 函数刚好能解决这个问题,它可以在分组时返回组内任意一个指定字段的值,用法非常直接:
SELECT PartNumber, ANY_VALUE(Description) AS Description, SUM(TotQtySold) AS TotalQtySold, year FROM partsTable GROUP BY PartNumber, year;
逻辑说明:分组维度只保留 PartNumber 和 year,ANY_VALUE() 会自动取该组存储顺序里的第一个描述(也可以理解为任意一个),同时把同组的销量求和。
2. SQL Server / Azure SQL 实现
这类数据库可以用窗口函数来标记每组的第一条记录,再筛选出目标结果:
WITH rankedParts AS ( SELECT PartNumber, Description, TotQtySold, year, -- ORDER BY (SELECT NULL) 表示不指定排序,直接取组内第一条 ROW_NUMBER() OVER (PARTITION BY PartNumber, year ORDER BY (SELECT NULL)) AS rn ) SELECT PartNumber, Description, SUM(TotQtySold) AS TotalQtySold, year FROM rankedParts WHERE rn = 1 GROUP BY PartNumber, Description, year;
嫌CTE麻烦的话,也可以用 FIRST_VALUE() 窗口函数直接生成结果:
SELECT DISTINCT PartNumber, FIRST_VALUE(Description) OVER (PARTITION BY PartNumber, year ORDER BY (SELECT NULL)) AS Description, SUM(TotQtySold) OVER (PARTITION BY PartNumber, year) AS TotalQtySold, year FROM partsTable;
3. PostgreSQL 实现
PostgreSQL 支持 DISTINCT ON 语法,能一步到位获取每组的第一条记录并完成求和:
SELECT DISTINCT ON (PartNumber, year) PartNumber, Description, SUM(TotQtySold) OVER (PARTITION BY PartNumber, year) AS TotalQtySold, year FROM partsTable ORDER BY PartNumber, year;
逻辑说明:DISTINCT ON (PartNumber, year) 会保留每组的第一条记录,SUM() OVER() 则对整个组的销量求和,最终得到合并后的结果。
测试数据验证
用你给出的测试数据:
PartNumber|Description|TotQtySold|year ABC123 |Repair Kit |5 |2007 ABC123 |kit |3 |2007 ABC123 |Repair kit |8 |2007
以上任意方案都会返回你想要的结果:
PartNumber|Description|TotalQtySold|year ABC123 |Repair Kit |16 |2007
(注:如果是随机取描述,偶尔可能返回其他值,但你要求任意一个,完全符合需求)
内容的提问来源于stack exchange,提问作者Garrett Pe
相关产品推荐
相关产品推荐

