代码之家  ›  专栏  ›  技术社区  ›  Sukhjeevan

需要有关SELECT子句中CASE语句的T-SQL帮助

  •  1
  • Sukhjeevan  · 技术社区  · 11 年前

    什么是最佳方法

    接近-I

    SELECT 
    SUM(CASE WHEN CODE = 'A' THEN ISNULL(UNIT,0.00)+ISNULL(UNIT_1,0.00) END) AS UNIT_SUM
    FROM tblA
    

    方法二

    SELECT 
    ISNULL(SUM(CASE WHEN CODE = 'A' THEN UNIT+UNIT_1 END),0.00) AS UNIT_SUM
    FROM tblA
    

    1) 我担心的是,我必须把ISNULL放在CASE语句内部还是放在CASE语句外部。 它会影响单位的总和吗?或者两个查询都给出相同的结果。 如果任何UNIT列的值为NULL,会发生什么?这会导致总数为NULL吗。

    2) 我必须在CASE语句中使用ELSE吗?如下所示:

    那么。。。 其他0.00

    6 回复  |  直到 11 年前
        1
  •  2
  •   roman    11 年前

    你有其他答案指出你最好把你的过滤器 = 'A' 进入where子句以加快查询速度,这是正确的做法。 我还想注意的是,如果没有要求和的行,您的查询会产生不同的结果:

    SELECT 
    ISNULL(SUM(CASE WHEN CODE = 'A' THEN UNIT END),0.00) AS UNIT_SUM
    FROM tblA;
    -- output: 0
    
    SELECT 
    SUM(CASE WHEN CODE = 'A' THEN ISNULL(UNIT,0.00) END) AS UNIT_SUM
    FROM tblA;
    -- output: null
    

    如果您想获得所有行的总和,并将这些数据放入列中,可以使用以下查询:

    select
        isnull(sum(case when code = 'A' then unit end), 0) as [A],
        isnull(sum(case when code = 'B' then unit end), 0) as [B]
    from tblA
    -- filter out rows if there's more codes in your table
    where code in ('A', 'B')
    

    sql fiddle demo

        2
  •  1
  •   peterm    11 年前

    对原问题的回答:

    我必须在CASE语句中放置ISNULL吗。。。?

    不,你没有。 SUM() 忽略 NULL 因此,NULL值的存在不会影响求和的结果。例外情况是所有值都为NULL,或者根本没有任何值。那样的话,你会得到 无效的 因此

    我必须在CASE语句中使用ELSE吗。。?

    不,你不这么做也是出于同样的原因。

    …我需要使用吗 ISNULL() 外部 CASE ..?

    这取决于当所有值都为 无效的 s,否则您没有任何值。如果你想拥有 0 或任何其他值,然后使用 不是() COALESCE() 。否则不要。

    这是 SQLFiddle 演示

    更新

    给出你改变后的问题中类似的表达

    SUM(CASE WHEN CODE = 'A' THEN UNIT + UNIT_1 END)
    

    你很可能想使用 不是() 联合() 在两者周围 UNIT UNIT_1 如果您想将其中一列的缺失值视为零值。 在这种情况下,如果您想在结果集中获得零,即使没有与您的 案例 调节你 仍然需要 使用 不是() 联合() 围绕 总和() .

    SELECT ISNULL(SUM(CASE WHEN CODE = 'A' 
                           THEN ISNULL(UNIT, 0) + ISNULL(UNIT_1, 0) 
                      END), 0) AS UNIT_SUM
    

    SELECT COALESCE(SUM(CASE WHEN CODE = 'A' 
                             THEN COALESCE(UNIT, 0) + COALESCE(UNIT_1, 0) 
                        END), 0) AS UNIT_SUM
    

    这是 SQLFiddle 演示

        3
  •  1
  •   Tom Chantler    11 年前

    如果你只想得到以下情况的总和 CODE='A' ,那么我会这样写:

    SELECT ISNULL(SUM(UNIT),0.00) AS UNIT_SUM
    FROM tblA
    WHERE CODE = 'A'
    

    如果您也在选择其他列,那么我会这样做:

    SELECT ISNULL(SUM(CASE WHEN CODE = 'A' THEN UNIT ELSE 0.00 END)) AS UNIT_SUM
    FROM tblA
    
        4
  •  1
  •   dani herrera    11 年前

    不管怎样,正确的方法是:

    SELECT 
    ISNULL(SUM(UNIT),0.00) AS UNIT_SUM
    FROM tblA
    WHERE CODE = 'A'    --<------------ Index friendly
    

    你的方法很糟糕,因为它对索引不友好 此外,对于case语句,您应该评估每一行。

    如果有更多列要聚合,则可以执行CTE查询,然后联接结果:

    ;with cte_a as (
        SELECT 
        coalesce(SUM(UNIT),0.00) AS UNIT_SUM_A
        FROM tblA
        WHERE CODE = 'A'
    ),
    cte_b as (
        SELECT 
        coalesce(SUM(UNIT),0.00) AS UNIT_SUM_B
        FROM tblA
        WHERE CODE = 'B'
    )
    SELECT UNIT_SUM_A, UNIT_SUM_B
    FROM cte_a cross join cte_b b 
    

    已编辑 @RomanPekar评论的第二个问题。

        5
  •  0
  •   athabaska    11 年前

    如果你使用方法II,你就不需要ELSE,所以我想就代码更少而言,这更好。

        6
  •  0
  •   dnoeth    11 年前

    两种变体返回相同的结果:

    第一个将NULL替换为零 之前 SUM和第二个替换NULL 之后 SUM,即没有带“A”的行。

    顺便说一句,我会用标准SQL COALESCE(UNIT,0.00)代替专有的ISNULL。

    当然,您可以简单地将其替换为:

    CASE WHEN CODE = 'A' THEN UNIT ELSE 0.00 END