Sql 将SUM和CASE组合返回0?
对于SQL Server,我实际上是在尝试根据年初至今的数据计算一个值,所以我想对2012年7月16日及之前的所有值求和并显示它们。我使用以下查询注意,我已将参数替换为简单整数来计算今天的值:Sql 将SUM和CASE组合返回0?,sql,sql-server,Sql,Sql Server,对于SQL Server,我实际上是在尝试根据年初至今的数据计算一个值,所以我想对2012年7月16日及之前的所有值求和并显示它们。我使用以下查询注意,我已将参数替换为简单整数来计算今天的值: SELECT SUM(CASE WHEN ( ( dns.ODAY <= 16 AND (dns.fiscalyear + 1) = 13 AND dns.omo
SELECT SUM(CASE
WHEN (
(
dns.ODAY <= 16
AND (dns.fiscalyear + 1) = 13
AND dns.omonth = 7
)
OR
(
(dns.fiscalyear + 1) = 13
AND dns.omonth < 7
)
)
THEN dns.QtyShipped
ELSE 0
END) AS Shipped_Units
FROM myTable dns
但是,此查询为所有行返回0。如果我将dns.QtyShipped替换为整数,例如1,它仍然返回0。因此,很明显,case语句没有得到正确的计算。我的逻辑有缺陷吗?或者是语法问题,例如我需要更多的括号
谢谢
补充意见:
为了测试,我运行了以下查询:
SELECT SUM(dns.QtyShipped)
FROM myTable dns
where
(dns.ODAY <= 16
AND (dns.fiscalyear + 1) = 13
AND dns.omonth = 7)
OR
((dns.fiscalyear + 1) = 13
AND dns.omonth < 7)
返回一个非常大的数字。这让人困惑。您前面提到的代码工作得非常好。请仔细检查用于评估条件的值。例如,请确认财政年度的值是2013年还是13年。在下面提到的代码中,我使用了变量而不是列名,并返回了预期的结果:
declare @ODAY integer
set @ODAY=17
declare @fiscalyear int
set @fiscalyear=12
declare @omonth int
set @omonth=8
SELECT SUM(CASE
WHEN (
(
@ODAY <= 16
AND (@fiscalyear + 1) = 13
AND @omonth = 7
)
OR
(
(@fiscalyear + 1) = 13
AND @omonth < 7
)
)
THEN 1
ELSE 0
END) AS Shipped_Units
您前面提到的代码运行得非常好。请仔细检查用于评估条件的值。例如,请确认财政年度的值是2013年还是13年。在下面提到的代码中,我使用了变量而不是列名,并返回了预期的结果:
declare @ODAY integer
set @ODAY=17
declare @fiscalyear int
set @fiscalyear=12
declare @omonth int
set @omonth=8
SELECT SUM(CASE
WHEN (
(
@ODAY <= 16
AND (@fiscalyear + 1) = 13
AND @omonth = 7
)
OR
(
(@fiscalyear + 1) = 13
AND @omonth < 7
)
)
THEN 1
ELSE 0
END) AS Shipped_Units
如果我不得不猜测的话,我会说你的年份被存储为4位数字。至少这是我在设置测试时遇到的问题 当我设置此测试时,它起了作用:
CREATE TABLE myTable (fiscalyear int, omonth int, ODAY int, qtyshipped int)
INSERT INTO myTable VALUES (2012,1,1,1),
(12,1,1,1),
(12,2,1,1),
(12,3,1,1),
(12,4,1,1),
(13,1,1,1),
(12,7,1,1)
当我设置此测试时,它失败了:
CREATE TABLE myTable (fiscalyear int, omonth int, ODAY int, qtyshipped int)
INSERT INTO myTable VALUES (2012,1,1,1),
(2012,1,1,1),
(2012,2,1,1),
(2012,3,1,1),
(2012,4,1,1),
(2013,1,1,1),
(2012,7,1,1)
有什么理由不使用实际日期吗?您的逻辑会简单得多,如果日期存储在表中,那么查询可能也会更快
编辑:这里有一个附加测试,您可以运行该测试以确保是您的情况导致问题:
SELECT SUM(CASE
WHEN (
(
dns.ODAY <= 16
AND (dns.fiscalyear + 1) = 13
AND dns.omonth = 7
)
OR
(
(dns.fiscalyear + 1) = 13
AND dns.omonth < 7
)
)
THEN 0
ELSE dns.QtyShipped
END) AS Shipped_Units
FROM myTable dns
基本上把这个案子翻过来。如果为true,则返回0;如果为false,则返回QtyShipped。如果你这样得到一个值,那么问题就在你的情况下,如果你不这样做,那么问题可能在你查询的其他地方。如果我不得不猜测,我会说你的年份被存储为4位数字。至少这是我在设置测试时遇到的问题 当我设置此测试时,它起了作用:
CREATE TABLE myTable (fiscalyear int, omonth int, ODAY int, qtyshipped int)
INSERT INTO myTable VALUES (2012,1,1,1),
(12,1,1,1),
(12,2,1,1),
(12,3,1,1),
(12,4,1,1),
(13,1,1,1),
(12,7,1,1)
当我设置此测试时,它失败了:
CREATE TABLE myTable (fiscalyear int, omonth int, ODAY int, qtyshipped int)
INSERT INTO myTable VALUES (2012,1,1,1),
(2012,1,1,1),
(2012,2,1,1),
(2012,3,1,1),
(2012,4,1,1),
(2013,1,1,1),
(2012,7,1,1)
有什么理由不使用实际日期吗?您的逻辑会简单得多,如果日期存储在表中,那么查询可能也会更快
编辑:这里有一个附加测试,您可以运行该测试以确保是您的情况导致问题:
SELECT SUM(CASE
WHEN (
(
dns.ODAY <= 16
AND (dns.fiscalyear + 1) = 13
AND dns.omonth = 7
)
OR
(
(dns.fiscalyear + 1) = 13
AND dns.omonth < 7
)
)
THEN 0
ELSE dns.QtyShipped
END) AS Shipped_Units
FROM myTable dns
基本上把这个案子翻过来。如果为true,则返回0;如果为false,则返回QtyShipped。如果您通过这种方式获得一个值,那么问题就在您的情况下,如果您不这样做,那么问题可能在查询的其他地方。dns.fiscalyear+1=13永远都不是真的?;B dns.omonth始终大于7?;二者的结合。。。你能发布dns表定义吗?B dns.omonth<7从来都不是真的?你怎么知道你有与你的情况匹配的数据?很好。我编辑了我的问题,以显示我有与我的案例相匹配的数据。你能将每个测试查询返回的第一条记录添加到问题中吗?dns.fiscalyear+1=13从来都不是真的吗?;B dns.omonth始终大于7?;二者的结合。。。你能发布dns表定义吗?B dns.omonth<7从来都不是真的?你怎么知道你有与你的情况匹配的数据?很好。我编辑了我的问题,以显示我有与我的案例相匹配的数据。您能否将每个测试查询返回的第一条记录添加到问题中?不幸的是,数据库是多年前由我们的客户设置的,不符合最佳做法。年份确实存储为两位数,这令人困惑。不幸的是,该数据库是由我们的客户多年前建立的,不符合最佳实践。年份实际上是以两位数的形式存储的,这令人费解。