SUM和CASE的组合返回0?

时间:2013-07-17 14:09:55

标签: sql sql-server

对于SQL Server,我实际上是在尝试根据年初日期来计算一个值,所以我想对2012年7月16日及之前的任何值求和并显示它们。我正在使用以下查询(请注意,我已使用简单整数替换参数来计算今天的值):

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)

返回非常大的数字。这很令人困惑。

2 个答案:

答案 0 :(得分:3)

您之前提到的代码工作正常。请仔细检查您用于评估条件的值。例如,请确认fiscalyear的值是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

答案 1 :(得分:1)

如果我不得不猜我会说你的年份存储为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

基本上翻转一下这个案子。如果您是真,则返回0,否则返回QtyShipped。如果你以这种方式得到一个值,那么问题出现在你的情况下,如果你没有,那么问题可能就在你的查询中的其他地方。