计算SQL中不同行的值之间的差异

时间:2016-04-19 08:06:17

标签: sql-server-2008 partition

我有一张这样的表:

Month_Date Account Cash 
1          2222    5000   
2          2222    6000  
3          2222    7000 
4          2222    10000 
2          1111    5000   
3          1111    7000  
4          1111    8000  

我想要的输出应该是这样的:

Month_Date Account Cash diff
1          2222    5000   NA
2          2222    6000  1000/5000= 0.2
3          2222    7000  1000/6000= 0.16
4          2222    10000 3000/7000 = 0.42
2          1111    5000   NA
3          1111    7000  2000/5000= 0.4
4          1111    8000  1000/7000= 0.14

没有计算过程。 并非所有帐户都有来自第1个月的数据,请参阅帐户1111,因此我考虑对其进行排名。 我正在寻找类似于减去和划分帐户分区的行的东西。

Select Month_Date, Account, Cash, 
rank() over (Partition by Month_Date, Account) order by Month_Date as Rnk, 
Diff = 
case when Rnk = 1 then 'NA' else ????

任何建议如何执行此操作?

2 个答案:

答案 0 :(得分:1)

适用于SQL Server 2012之前

SELECT
    M.Month_Date,
    M.Account,
    M.Cash,
    Diff = X.Cash -  M.Cash
FROM
    MyTable M
    OUTER APPLY
    (SELECT TOP 1
        *
    FROM
        MyTable M2
    WHERE
        M.Account = M2.Account
        AND
        M.Month_Date < M2.Month_Date
    ORDER BY
        Month_Date
    ) X

答案 1 :(得分:1)

对于SQL Server 2012+,您可以使用LAG / LEAD个功能。在SQL Server 2008中,您可以使用outer apply运算符来确定上一行:

DECLARE @t TABLE
    (
      Month_Date INT ,
      Account INT ,
      Cash INT
    )
INSERT  INTO @t
VALUES  ( 1, 2222, 5000 ),
        ( 2, 2222, 6000 ),
        ( 3, 2222, 7000 ),
        ( 4, 2222, 10000 ),
        ( 2, 1111, 5000 ),
        ( 3, 1111, 7000 ),
        ( 4, 1111, 8000 )

SELECT t.*, ROUND((t.Cash - oa.Cash) * 1.0 / oa.Cash, 2) AS Diff
FROM @t t
OUTER APPLY(SELECT TOP 1 * FROM @t 
            WHERE Account = t.Account AND 
                  Month_Date < t.Month_Date 
            ORDER BY Month_Date DESC) oa

输出:

Month_Date  Account Cash    Diff
1           2222    5000    NULL
2           2222    6000    0.200000000000
3           2222    7000    0.170000000000
4           2222    10000   0.430000000000
2           1111    5000    NULL
3           1111    7000    0.400000000000
4           1111    8000    0.140000000000