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

关于SELECT子句中的CASE语句,需要T-SQL帮助,sql,sql-server,tsql,Sql,Sql Server,Tsql,最好的方法是什么 方法一 方法二 1我关心的是我是否必须在CASE语句内部或外部CASE语句中放置ISNULL。 它是否影响单位的总和,或者两个查询都给出相同的结果。 若任何单位列都有空值会发生什么?它是否会导致总计为空 2我是否必须在下面给出的案例陈述中使用ELSE: 然后。。。ELSE 0.00 END如果你使用方法II,你不需要ELSE,所以我想代码越少越好。如果你使用方法II,你不需要其他,所以我想代码越少越好。如果你只需要代码为A'的情况的总和,那么我会这样写: SELECT ISNU

最好的方法是什么

方法一

方法二

1我关心的是我是否必须在CASE语句内部或外部CASE语句中放置ISNULL。 它是否影响单位的总和,或者两个查询都给出相同的结果。 若任何单位列都有空值会发生什么?它是否会导致总计为空

2我是否必须在下面给出的案例陈述中使用ELSE:


然后。。。ELSE 0.00 END

如果你使用方法II,你不需要ELSE,所以我想代码越少越好。

如果你使用方法II,你不需要其他,所以我想代码越少越好。

如果你只需要代码为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
如果您也选择了其他列,那么我会这样做:

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

如果您只需要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
如果您也选择了其他列,那么我会这样做:

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

无论哪种方法,正确的方法都是:

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

由@RomanPekar comment编辑的第二个查询。

或者,正确的方法是:

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

由@RomanPekar comment编辑的第二个查询。

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

第一个在和之前用零替换空值,第二个在和之后用空值替换空值,即没有带“a”的行

顺便说一句,我会用标准的SQL合并单元0.00替换专有的ISNULL

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

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

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

第一个在和之前用零替换空值,第二个在和之后用空值替换空值,即没有带“a”的行

顺便说一句,我会用标准的SQL合并单元0.00替换专有的ISNULL

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

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

您还有其他答案指出,最好将filter='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')

您还有其他答案指出,最好将filter='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')
对原问题的答复:

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

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

我是否必须在CASE语句中使用ELSE

不,出于同样的原因,你没有

…我是否需要在CASE外部使用ISNULL

这取决于当所有值都为Null或没有任何值时,结果集中的期望值。如果想要0或任何其他值,请使用ISNULL或COALESCE。否则不要

这是演示

更新

给出了你的问题中的一个表达

SUM(CASE WHEN CODE = 'A' THEN UNIT + UNIT_1 END)
如果希望将其中一列的缺失值视为零值,则最有可能在UNIT和UNIT_1周围使用ISNULL或COALESCE。 在这种情况下,如果您希望在结果集中获得零,即使没有与您的案例条件匹配的值,您仍然需要使用ISNULL或COALESCE-around-SUM

当代码='A'时,选择ISNULLSUMCASE 然后ISNULLUNIT,0+ISNULLUNIT_1,0 结束,0作为单位和 或

以下是对原始问题的演示回答:

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

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

我是否必须在CASE语句中使用ELSE

不,出于同样的原因,你没有

…我是否需要在CASE外部使用ISNULL

这取决于当所有值都为Null或没有任何值时,结果集中的期望值。如果想要0或任何其他值,请使用ISNULL或COALESCE。否则不要

这是演示

更新

给出了你的问题中的一个表达

SUM(CASE WHEN CODE = 'A' THEN UNIT + UNIT_1 END)
如果希望将其中一列的缺失值视为零值,则最有可能在UNIT和UNIT_1周围使用ISNULL或COALESCE。 在这种情况下,如果您希望在结果集中获得零,即使没有与您的案例条件匹配的值,您仍然需要使用ISNULL或COALESCE-around-SUM

当代码='A'时,选择ISNULLSUMCASE 然后ISNULLUNIT,0+ISNU LLU单位1,0 结束,0作为单位和 或



这里是演示

将isnull置于外部只会影响sum的总结果。当您尝试各种可能性时会发生什么情况?对于我尝试过的一些结果集,两者都会给出相同的结果。因为在将来记录会增加,所以我认为最好的方法将isnull置于外部只会影响sum的总结果。当发生时你尝试过这些可能性吗?我尝试过一些结果集,它们都给出了相同的结果。因为在未来的记录会增加,这是我看起来最好的方法。如果没有行来统计,它可能会产生不同的结果。你是对的。我假设这不是完整的查询,将有其他一些列或一个GROUP BY other_列。如果没有正确的行,它可能会产生不同的结果。我假设这不是完整的查询,将有一些其他列或一组其他列。第二个查询非常难看,根本不可归纳,甚至可以改进交叉连接而不是完全外部连接,将“总计”移动到最终选择。在生产代码中看到这样的查询我会感到震惊。第二个查询真的很难看,根本不可归纳,甚至可以改进交叉连接而不是完全外部连接,将“total”移到final select中。在生产代码中看到这样的查询我会感到震惊。一个接一个地计算总数并最终加入它们会更加优雅。你的问题根本无法概括。仅仅为了提高性能而在where子句中包含filter是不优雅的。一种与易维护代码不匹配的冗余代码。当语句长大后很容易陷入矛盾。我不认为一个接一个地计算总数会更优雅,试着用10个元素来计算,你们知道为什么了。至于我的查询,它更具普遍性,但我认为有一种改进的方法,当sqlfiddle解决一些问题时,我会尝试使用它。现在,一个接一个地计算总数并最终加入它们会更优雅。你的问题根本无法概括。仅仅为了提高性能而在where子句中包含filter是不优雅的。一种与易维护代码不匹配的冗余代码。当语句长大后很容易陷入矛盾。我不认为一个接一个地计算总数会更优雅,试着用10个元素来计算,你们知道为什么了。关于我的查询-它更具普遍性,但我认为有一种方法可以改进它,当sqlfiddle解决一些问题时,我会尝试使用它。这是问题解决方案的最接近答案。我对问题中的CASE satement做了一些小的更改。请检查。@Sukhi这在您的问题中是非常剧烈的更改。请参阅更新的答案。简言之,在这种情况下,您很可能希望在总和聚合的内部和外部都使用ISNULL。@Sukhi好极了。我很高兴我能帮上忙:祝你好运。这是最接近问题解决方案的答案。我对问题中的情况做了一些小改动。请检查。@Sukhi,这是你问题中非常剧烈的改动。请参阅更新的答案。简言之,在这种情况下,您很可能希望在总和聚合的内部和外部都使用ISNULL。@Sukhi好极了。我很高兴能帮上忙:祝你好运。