SQL Server:无需UNION实现非Null ID的Value求和、Null ID保留原值
解决SQL Server中ID非空求和、空值保留原值的问题
需求说明
现有SQL Server表包含ID和Value两列,ID存在重复值与Null值:
| ID | Value |
|---|---|
| 1 | 10 |
| 1 | 20 |
| 1 | 20 |
| 2 | 25 |
| 2 | 15 |
| 3 | 30 |
| Null | 5 |
| Null | 10 |
要求实现:
- 当
ID不为Null时,对同一ID对应的Value列求和 - 当
ID为Null时,直接保留Value原值 - 无需使用
UNION语句,改用IIF/CASE函数实现
问题分析
你尝试的IIF(ID is not null,sum([Value]),[Value])写法无效,原因是SUM()是聚合函数,一旦使用聚合函数,SQL会触发全表聚合逻辑,Null行的Value会被强制参与聚合,无法单独保留原值。
解决方案
方案1:窗口函数+DISTINCT
利用窗口函数SUM() OVER(PARTITION BY ID)为每个非Null的ID计算总和,Null行直接取原值,最后通过DISTINCT去重非NullID的重复行:
SELECT DISTINCT ID, IIF(ID IS NOT NULL, SUM(Value) OVER(PARTITION BY ID), Value) AS Value FROM YourTable;
(也可以把IIF换成CASE语句,逻辑完全一致)
方案2:GROUP BY结合分组区分Null行
通过CASE为每个Null行生成唯一分组标识,确保Null行单独分组保留原值,非Null行按ID分组求和:
SELECT ID, SUM(Value) AS Value FROM YourTable GROUP BY ID, CASE WHEN ID IS NULL THEN NEWID() ELSE '' END;
解释:NEWID()会生成唯一GUID,每个Null行的分组标识都不同,因此每个Null行单独成组,SUM(Value)结果就是原值;非Null行的分组标识统一为'',不影响按ID分组求和。
验证结果
两种方案都能得到与原UNION语句一致的结果:
| ID | Value |
|---|---|
| 1 | 50 |
| 2 | 40 |
| 3 | 30 |
| Null | 5 |
| Null | 10 |
内容的提问来源于stack exchange,提问作者Jatin Purswani
相关产品推荐
相关产品推荐

