【问题标题】:SQL: Sum of two columns containing NULLS?SQL:包含 NULLS 的两列的总和?
【发布时间】:2021-07-07 16:04:41
【问题描述】:

我想将两列相加得到第三列。如果一行的两列都有NULL,我希望第三列有NULL,而不是0。原因是因为我想获得第三列的平均值,而 0 会改变该平均值。

| Value1 | Value2 | Value3 |
|--------|--------|--------|
| 10     | NULL   | 10     |
| 20     | NULL   | 20     |
| NULL   | NULL   | NULL   |
| 20     | 30     | 50     |
| NULL   | NULL   | NULL   |

我尝试了以下方法,但它们都为NULL 行提供了0。实现这一目标的最佳方法是什么?

CREATE TABLE #AMOUNTS (
    Value1 INT,
    Value2 INT
)

INSERT INTO #AMOUNTS VALUES
(10, NULL), (20, NULL), (NULL, NULL), (20, 30), (NULL, NULL)

SELECT 
Value1, Value2

,ISNULL(Value1, 0) + ISNULL(Value2, 0) AS Value3
,COALESCE(Value1, 0) + COALESCE(Value2, 0) AS Value3
,CASE WHEN Value1 = NULL AND Value2 = NULL THEN NULL
    ELSE ISNULL(Value1, 0) + ISNULL(Value2, 0)
END AS Value3
FROM #AMOUNTS
| Value1 | Value2 | Value3 | Value3 | Value3 |
|--------|--------|--------|--------|--------|
| 10     | NULL   | 10     | 10     | 10     |
| 20     | NULL   | 20     | 20     | 20     |
| NULL   | NULL   | 0      | 0      | 0      |
| 20     | 30     | 50     | 50     | 50     |
| NULL   | NULL   | 0      | 0      | 0      |

【问题讨论】:

  • Value1 = NULL 永远不会是真的,NULL 不等于任何东西,包括NULL。你需要IS NULL

标签: sql sql-server aggregation


【解决方案1】:

在测试 NULL 时使用运算符 IS 而不是 =

CASE WHEN Value1 IS NULL AND Value2 IS NULL THEN NULL
ELSE ISNULL(Value1, 0) + ISNULL(Value2, 0)

【讨论】:

    【解决方案2】:

    使用case 表达式:

    select (case when value1 is null and value2 is null
                 then null
                 else coalesce(value1, 0) + coalesce(value2, 0)
            end)
    

    也就是说,apply 是一种获取平均值的简单方法:

    select t.*, v.avg_value
    from t cross apply
         (select avg(v.val) as avg_value
          from (values (value1), (value2)) v(val)
         ) v;
             
    

    【讨论】:

      【解决方案3】:

      如果您不想在结果列中出现0s,您可以使用ISNULL()NULLIF()

      SELECT *, NULLIF(ISNULL(Value1, 0) + ISNULL(Value2, 0), 0) Value3
      FROM Amounts
      

      请参阅demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多