SQL Server SSMS17中基于求和的双重透视需求问询
嘿,我来帮你搞定SQL Server里这个二次透视合并的需求!你说已经完成了第一次透视,但还需要第二次操作把同一u_id的多行数据合并成一行,还要展示总计列对吧?我给你分两种场景来讲解,直接上干货:
先明确场景:假设你的数据结构
先模拟下你的原始数据(方便后续举例),比如你的未透视表大概是这样的:
| u_id | CODE_1 | CODE_2 | VALUE |
|---|---|---|---|
| U01 | A | X | 10 |
| U01 | A | Y | 20 |
| U01 | B | X | 15 |
| U02 | A | X | 5 |
假设你第一次透视是按CODE_1分组,得到了中间结果,但同一u_id还是有多个PO_NUM的行,现在要把同一u_id的所有数据合并成一行,同时展示各类代码的计算值和总计。
方案一:基于第一次透视的中间结果做二次合并
如果你已经把第一次透视的结果存在临时表(比如#FirstPivot)里,结构大概是u_id, PO_NUM, CODE_A, CODE_B...,那直接用聚合函数+GROUP BY就能合并:
SELECT u_id, SUM(CODE_A) AS Total_CODE_A, -- 按u_id聚合CODE_A的总和 SUM(CODE_B) AS Total_CODE_B, -- 同理处理CODE_B -- 计算总计:把所有CODE的非空值加起来 SUM(ISNULL(CODE_A, 0) + ISNULL(CODE_B, 0)) AS Grand_Total FROM #FirstPivot GROUP BY u_id
这个语句会把同一u_id的所有行合并,自动聚合各CODE的值,最后算出总计。
方案二:直接一次完成双重透视(更高效,推荐)
如果你的原始数据里有两个代码维度(CODE_1和CODE_2),其实可以跳过中间表,直接一次完成两次透视的逻辑,把两个代码组合成新的列,再透视:
静态SQL(适合代码组合固定的情况)
如果你的CODE_1和CODE_2的组合是已知的(比如只有A_X、A_Y、B_X这几种),直接写静态SQL更简单:
SELECT u_id, -- 逐个处理每个代码组合的聚合值 SUM(CASE WHEN CONCAT(CODE_1, '_', CODE_2) = 'A_X' THEN VALUE ELSE 0 END) AS A_X, SUM(CASE WHEN CONCAT(CODE_1, '_', CODE_2) = 'A_Y' THEN VALUE ELSE 0 END) AS A_Y, SUM(CASE WHEN CONCAT(CODE_1, '_', CODE_2) = 'B_X' THEN VALUE ELSE 0 END) AS B_X, -- 总计列:直接求和所有VALUE SUM(VALUE) AS Grand_Total FROM YourOriginalTable -- 替换成你的原始表名 GROUP BY u_id
执行后会得到这样的结果,完美符合你“一行一个u_id”的需求:
| A_X | A_Y | B_X | Grand_Total |
|---|---|---|---|
| 10 | 20 | 15 | 45 |
| 5 | 0 | 0 | 5 |
动态SQL(适合代码组合不固定的情况)
如果你的CODE_1和CODE_2会新增组合,不想每次改SQL,就用动态SQL自动生成透视列:
DECLARE @PivotColumns NVARCHAR(MAX), @SQL NVARCHAR(MAX) -- 第一步:自动获取所有唯一的代码组合 SELECT @PivotColumns = STRING_AGG(QUOTENAME(CONCAT(CODE_1, '_', CODE_2)), ', ') FROM ( SELECT DISTINCT CODE_1, CODE_2 FROM YourOriginalTable -- 替换成你的原始表名 ) AS CodeCombinations -- 第二步:构建动态透视SQL SET @SQL = N' SELECT u_id, ' + @PivotColumns + ', SUM(VALUE) AS Grand_Total FROM ( SELECT u_id, CONCAT(CODE_1, ''_'', CODE_2) AS Combined_Code, VALUE FROM YourOriginalTable -- 替换成你的原始表名 ) AS CombinedCodes PIVOT ( SUM(VALUE) -- 这里替换成你需要的聚合函数,比如COUNT/AVG FOR Combined_Code IN (' + @PivotColumns + ') ) AS PivotTable GROUP BY u_id, ' + @PivotColumns -- 第三步:执行动态SQL EXEC sp_executesql @SQL
这个脚本会自动识别所有代码组合,生成对应的列,不用手动维护列名,非常灵活。
几个注意点
- 如果你的第一次透视用的不是
SUM(比如是COUNT或者AVG),把上面的聚合函数换成你需要的就行。 - 处理NULL值时,用
ISNULL(列名, 0)把NULL转成0,避免总计计算出错。 - 如果你是按其他维度(比如PO_NUM)第一次透视,只需要调整GROUP BY的字段就行。
内容的提问来源于stack exchange,提问作者DomRow
相关产品推荐
相关产品推荐

