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

时间:2013-09-16 07:17:18

标签: sql sql-server tsql

什么是最佳方法

方法-I

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

方法-II

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

1)我担心的是我必须将ISNULL放在CASE语句或outsite CASE语句中。 它是否影响单位的总和或两个查询都给出相同的结果。 如果任何UNIT列具有NULL值,会发生什么。结果是否为NULL。

2)我必须在CASE声明中使用ELSE,如下所示:

然后...... ELSE 0.00 结束

6 个答案:

答案 0 :(得分:2)

您还有其他答案指出您最好将过滤器= '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

答案 1 :(得分:1)

如果您只想要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

答案 2 :(得分:1)

或者,正确的方法是:

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评论。

答案 3 :(得分:1)

回答原始问题:

  

我是否必须将ISNULL放在CASE语句中??

不,不。 SUM()忽略NULL。因此,NULL值的存在不会影响求和的结果。例外情况是所有值都为NULL,或者根本没有任何值。在这种情况下,您将得到NULL

  

我是否必须在CASE声明中使用ELSE ..?

不,你不是出于同样的原因。

  

...我需要在ISNULL()之外使用CASE吗?

如果所有值都是NULL s或者您没有任何值,则取决于您对结果集的期望。如果您想拥有0或任何其他值,请使用ISNULL()COALESCE()。否则不要。

这是 SQLFiddle 演示

更新

在改变后的问题中给出一个表达式

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

如果您希望将其中一列的缺席值视为零值,则您最有可能在ISNULL()COALESCE()周围使用UNITUNIT_1。 在这种情况下,如果您希望在结果集中获得零,即使没有与CASE条件匹配的值,您仍然需要才能使用ISNULL()或{{1}围绕COALESCE()

SUM()

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

这是 SQLFiddle 演示

答案 4 :(得分:0)

如果你使用方法-II你不需要ELSE,所以我想在更少的代码方面更好。

答案 5 :(得分:0)

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

第一个用零替换NULL,在>之前用替换NULL,而在之后替换一个NULL ,即没有带'A'的行。

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

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

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