重置SQL中SUM子句的累积和

时间:2015-12-15 02:54:47

标签: sql sql-server

我遇到了一些SQL,并对重置累积金额有疑问。我不确定它是否可能,我发现的其他例子与我的略有不同。另一位SO成员帮我解决了这个问题,打印出一些订单的总数(这是一种完全不同于我之前尝试过的方法; SQL Statement With 'Totals' as Final Column)。这是具有一些新线的解决方案:

SELECT
  CASE 
    WHEN GROUPING(MONTH(orders.orderdate)) = 1 
    THEN 'Totals' 
    ELSE CONVERT(CHAR(2), MONTH(orders.orderdate)) 
  END AS [Month]
, SUM(
    CASE 
        WHEN YEAR(orders.orderdate) = Datepart(yy, Dateadd(mm, -1, CURRENT_TIMESTAMP))
        THEN 
            CASE
                WHEN MONTH(orders.orderdate) = 01 or MONTH(orders.orderdate) = 02 or MONTH(orders.orderdate) = 03 or MONTH(orders.orderdate) = 04 MONTH(orders.orderdate) = 05
                THEN 1.54
                ELSE orders.total_payment_received
            END
        ELSE 0.00 
    END
    )   AS PaymentReceived_LastYear
, SUM(
    CASE 
        WHEN YEAR(orders.orderdate) = Datepart(yy, Dateadd(mm, -13, CURRENT_TIMESTAMP))
        THEN orders.total_payment_received
        ELSE 0.00 
    END
    )   AS PaymentReceived_LastYear 
FROM   
    orders 
GROUP BY   
    MONTH(orders.orderdate)
WITH ROLLUP

嵌套的CASE语句是我被绊倒的地方。除了今年1月,2月,3月,4月和5月的价值之外,我基本上想要获得所有这些月份的价值。 INSTEAD,我想将这些月份设置为显式值。在这种情况下,我将它们全部设置为1.54,但是一旦我能够解决这个问题,我将更新所有这几个月的值。但是,当我这样做的时候,它确实(正如预期的那样)每次看到其中一个月的时候,它会为那个月的前一个值增加1.54。

这是我运行时得到的结果(顺便说一句,我捏造数字不提供实时数据;实际上你只是看看paymentreceived_lastyear下的1和5的值:

month   paymentreceived_lastyear    paymentreceived_lastyear
1       620.62                      765707960.7
2       0                           16577632.06
3       0                           95678.83
4       0                           7657.26
5       340.34                      78768.77
6       15650809.66                 9787876.52
7       22865443.89                 1765153.61
8       27652860.86                 67584.48
9       15563227.11                 745.4
10      15650478.29                 74657765452.67
11      92757668.09                 65765438.12
12      38675157.93                 176519535.45
Totals  75727606.79                 1267508279.87

这意味着第一个月发生了403次订单(403 * 1.54等于620.62;它是对它进行求和;第五个月为221次相同的逻辑)。根据我的代码,我希望它是这样的:

month   paymentreceived_lastyear    paymentreceived_lastyear
1       1.54                        765707960.7
2       0                           16577632.06
3       0                           95678.83
4       0                           7657.26
5       1.54                        78768.77
6       15650809.66                 9787876.52
7       22865443.89                 1765153.61
8       27652860.86                 67584.48
9       15563227.11                 745.4
10      15650478.29                 74657765452.67
11      92757668.09                 65765438.12
12      38675157.93                 176519535.45
Totals  75727606.79                 1267508279.87

我希望它只是重置这些值的累积总和,并显示我为这些月份设置的任何值(稍后我会填写实际值)。理想情况下,1到5之间的每个月都有能力拥有自己的静态值。

我想要重置SUM子句中的值,确定我是否重置它然后声明变量,最后一次通过'循环'它将重置它并将其声明为变量OR如果我可以直接声明一个静态值也很好。

有什么想法吗?我没有完全访问数据库,但出于我的目的,我只使用orders.orderdate(日期值)和orders.total_payment_received这是一个浮点值。

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

计算Jan - >的开始和结束日期。 May group(2015-01-01至2015-06-01)并将它们分配给变量。

然后使用这些日期对要汇总的项进行分区,因此SUM语句如下所示:

..
SUM(
    CASE 
        WHEN orderdate < @start 
            THEN 0.00 
        WHEN orderdate >= @end
            THEN total_payment_received
        ELSE 
            CASE DATEPART(MONTH, orderDate)
                WHEN 1
                    THEN 1.54
                WHEN 2 
                    THEN 1.54
                WHEN 3 
                    THEN 1.54
                WHEN 4 
                    THEN 1.54
                WHEN 5
                    THEN 1.54
            END
    END
    )  AS PaymentReceived_LastYear
...

答案 1 :(得分:0)

而不是编辑我的原始答案(我将其留作羞耻的标记),这是一个新的答案,基于原始代码的这个片段。如果您想使用表来保存&#34;每月覆盖&#34;这些值在这里可以很好地工作 - 临时表或永久表。我的例子包括使用永久表。

首先,我们设置表格:

CREATE TABLE Overrides (
    [Month] char(2) NOT NULL PRIMARY KEY,
    amount decimal(9,2) NOT NULL
    )  

INSERT INTO Overrides ([Month], amount) VALUES
    ('01', 1.54),           -- NOTE: This was new in SQL 2012. If your version is older, 
    ('02', 1.54),           --       use separate INSERT statements
    ('03', 1.54),
    ('04', 1.54),
    ('05', 1.54)

然后修改基本代码以使其工作,使原始查询成为最终SELECT

的派生表
SELECT 
CASE 
    WHEN GROUPING([month]) = 1 
        THEN 'Totals' 
    ELSE O.[Month]
END AS [Month],
ISNULL(O.amount, PaymentReceived_LastYear) AS PaymentReceived_LastYear,
PaymentReceived_PriorYear  
FROM ( 
    SELECT
        CONVERT(CHAR(2), MONTH(orders.orderdate)) 
        END AS [Month]
    , SUM(
        CASE 
            WHEN YEAR(orders.orderdate) = Datepart(yy, Dateadd(mm, -1, CURRENT_TIMESTAMP))
            THEN 
                CASE
                    WHEN MONTH(orders.orderdate) IN (SELECT [Month] FROM Overrides)
                    THEN 0.00
                    ELSE orders.total_payment_received
                END
            ELSE 0.00 
        END
        )   AS PaymentReceived_LastYear
    , SUM(
        CASE 
            WHEN YEAR(orders.orderdate) = Datepart(yy, Dateadd(mm, -13, CURRENT_TIMESTAMP))
            THEN orders.total_payment_received
            ELSE 0.00 
        END
        )   AS PaymentReceived_PriorYear 
    FROM   
        orders 
    GROUP BY   
        MONTH(orders.orderdate)
    ) AS base
LEFT JOIN Overrides AS O
    ON base.[Month] = O.[Month]
WITH ROLLUP

通过这些更改,您应该得到您想要的内容。