SQL Server视图转置表时负数显示为0的解决方法求助
问题描述
在SQL Server中创建视图转置包含正负数值的表时,所有负数都被返回为0,如何解决该问题?
原表示例
| Year | Peak | Value_A | Value_B |
|---|---|---|---|
| 2016 | AM | 15.156546 | 51.265146 |
| 2018 | AM | -15.5998 | -14.1565 |
| 2028 | AM | 16.3216 | 18.5611 |
| 2016 | IP | -0.01656 | -0.0026554 |
| 2018 | IP | -0.00159 | -0.59874 |
| 2028 | IP | 1.98438 | 3.362498 |
| 2016 | PM | -5.65436 | 8.6951 |
| 2018 | PM | 2.2316 | 3.859117 |
| 2028 | PM | -3.99842 | -9.620148 |
转置视图的错误结果
| Peak | Value_A_2016 | Value_A_2018 | Value_A_2028 | Value_B_2016 | Value_B_2018 | Value_B_2028 |
|---|---|---|---|---|---|---|
| AM | 15.156546 | 0 | 16.3216 | 51.265146 | 0 | 18.5611 |
| IP | 0 | 0 | 1.98438 | 0 | 0 | 3.362498 |
| PM | 0 | 2.2316 | 0 | 8.6951 | 3.859117 | 0 |
原视图SQL脚本
SELECT Peak, MAX(CASE WHEN T .YEAR = 2016 THEN T .[Value_A] ELSE 0.00 END) AS Value_A_2016, MAX(CASE WHEN T .YEAR = 2018 THEN T .[Value_A] ELSE 0.00 END) AS Value_A_2018, MAX(CASE WHEN T .YEAR = 2028 THEN T .[Value_A] ELSE 0.00 END) AS Value_A_2028, MAX(CASE WHEN T .YEAR = 2016 THEN T .[Value_B] ELSE 0.00 END) AS Value_B_2016, MAX(CASE WHEN T .YEAR = 2018 THEN T .[Value_B] ELSE 0.00 END) AS Value_B_2018, MAX(CASE WHEN T .YEAR = 2028 THEN T .[Value_B] ELSE 0.00 END) AS Value_B_2028 FROM gisadmin.Table_1 AS T GROUP BY Peak
解决方案
问题原因
使用MAX()聚合函数时,当CASE语句匹配到负数,0的数值比负数大,MAX()会选择0而非负数,导致所有负数被替换为0。
修改后的SQL脚本
提供两种可行的修改方案:
方案1:使用SUM()聚合函数(推荐)
SELECT Peak, SUM(CASE WHEN T.YEAR = 2016 THEN T.[Value_A] ELSE NULL END) AS Value_A_2016, SUM(CASE WHEN T.YEAR = 2018 THEN T.[Value_A] ELSE NULL END) AS Value_A_2018, SUM(CASE WHEN T.YEAR = 2028 THEN T.[Value_A] ELSE NULL END) AS Value_A_2028, SUM(CASE WHEN T.YEAR = 2016 THEN T.[Value_B] ELSE NULL END) AS Value_B_2016, SUM(CASE WHEN T.YEAR = 2018 THEN T.[Value_B] ELSE NULL END) AS Value_B_2018, SUM(CASE WHEN T.YEAR = 2028 THEN T.[Value_B] ELSE NULL END) AS Value_B_2028 FROM gisadmin.Table_1 AS T GROUP BY Peak
方案2:保留MAX(),将ELSE改为NULL
SELECT Peak, MAX(CASE WHEN T.YEAR = 2016 THEN T.[Value_A] ELSE NULL END) AS Value_A_2016, MAX(CASE WHEN T.YEAR = 2018 THEN T.[Value_A] ELSE NULL END) AS Value_A_2018, MAX(CASE WHEN T.YEAR = 2028 THEN T.[Value_A] ELSE NULL END) AS Value_A_2028, MAX(CASE WHEN T.YEAR = 2016 THEN T.[Value_B] ELSE NULL END) AS Value_B_2016, MAX(CASE WHEN T.YEAR = 2018 THEN T.[Value_B] ELSE NULL END) AS Value_B_2018, MAX(CASE WHEN T.YEAR = 2028 THEN T.[Value_B] ELSE NULL END) AS Value_B_2028 FROM gisadmin.Table_1 AS T GROUP BY Peak
方案说明
- 方案1中,
SUM()会忽略NULL值,若每个Peak+Year组合仅一条数据,结果等同于直接取该值;若有多条数据,会正确求和并保留负数。 - 方案2中,
MAX()同样忽略NULL值,匹配到负数时,该负数是分组内的唯一有效值,因此会被正确返回而非0。
内容的提问来源于stack exchange,提问作者Genspec
相关产品推荐
相关产品推荐

