2

针对 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)

它返回一个非常大的数字。这令人困惑。

4

2 回答 2

3

您之前提到的代码运行良好。请仔细检查您用于评估条件的值。例如,请确认会计年度的值是 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-07-17T14:22:31.040 回答
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

基本上把案子翻过来。如果您是 true,则返回 0,如果不是,则返回 QtyShipped。如果您以这种方式获得一个值,那么问题就出在您的情况下,如果您不这样做,那么问题可能出在您查询的其他地方。

于 2013-07-17T14:24:21.760 回答