计算sql中的delta(当前行和上一行的差异)

时间:2011-02-22 13:51:24

标签: sql mysql

我有一张像这样的表: trans是表的名称,例如

Id | Trans_Date          | Account_Id | Amount | Delta
------------------------------------------------------
1  | 2011-02-20 00:00:00 |     2      | 1200   | NULL
------------------------------------------------------
2  | 2011-03-21 00:00:00 |     2      | 2000   | NULL
------------------------------------------------------
3  | 2011-04-22 00:00:00 |     2      | 4500   | NULL
------------------------------------------------------
4  | 2011-02-20 00:00:00 |     4      | 1000   | NULL
------------------------------------------------------
5  | 2011-03-21 00:00:00 |     4      | 2400   | NULL
------------------------------------------------------
6  | 2011-04-22 00:00:00 |     4      | 3000   | NULL
------------------------------------------------------

我必须更新Delta列。假设每月有一个交易,哪个值是同一个帐户的当前行和同一个帐户的前一行的差异。 这是一个可以生成delta值的虚拟sql

select tt1.id, tt1.amount , tt1.AccountId,(tt1.amount-tt2.amount) as delta 
from trans tt1 left outer  JOIN trans  tt2 
on tt1.accountid = tt2.accountid
where month(tt1.date1)-month(tt2.date1)=1 ;

此查询的结果是

id | amount | AccountId  | delta  |
-------------------------------------
2  | 2000   |     2      | 800    | 
-------------------------------------
3  | 4500   |     2      | 2500   |
-------------------------------------
5  | 2400   |     4      | 1400   | 
-------------------------------------
6  | 3000   |     4      | 600    | 
-------------------------------------

但是没有任何前一行的行的增量应该是其数量,例如

1  | 1200   |     2      | 1200   | 
-----------------------------------------
4  | 1000   |     4      | 1000   | 
-----------------------------------------
顺便说一句,这些都是遗漏的。

请帮我解决此问题。

3 个答案:

答案 0 :(得分:10)

以下是相应修改的原始查询:

select
  tt1.id,
  tt1.amount,
  tt1.AccountId,
  (tt1.amount-ifnull(tt2.amount, 0)) as delta
from trans tt1
  left outer JOIN trans tt2 on tt1.accountid = tt2.accountid
    and month(tt1.date1)-month(tt2.date1)=1;

月份比较从where移至on,这对left join产生影响,tt2.amount替换为ifnull(tt2.amount, 0)


脚本的UPDATE版本:

update tt1
set delta = (tt1.amount-ifnull(tt2.amount, 0))
from trans tt1
  left outer JOIN trans tt2 on tt1.accountid = tt2.accountid
    and month(tt1.date1)-month(tt2.date1)=1;


上述更新的正确MySQL语法实际上应该是:

update trans tt1 
             left outer JOIN trans tt2 
             on tt1.accountid = tt2.accountid 
             and month(tt1.date1)-month(tt2.date1)=1 
set tt1.delta = (tt1.amount-ifnull(tt2.amount, 0));

(谢谢 @pinkb 。)

答案 1 :(得分:1)

您可以使用内部查询,但它不一定是最有效的查询。

UPDATE trans
SET Delta = Amount - 
(SELECT Amount FROM trans t1
WHERE t1.Trans_Date < trans.Trans_Date
ORDER BY t1.Trans_Date DESC LIMIT 1)

答案 2 :(得分:0)

您可以将查询“联合”查询,该查询只选择每个帐户的第一项,并将初始余额设置为增​​量,并将该记录的ID作为增量记录的ID吗?结果将按ID排序。很脏但是适用吗?

相关问题