[英]How to make a query that subtract value from a row and remaining value from next row order by date
[英]Subtract previous row value to current row and order by date
我表中的数据如下
SELECT ID, VALUE, acc_no, adate
FROM TB_DailyStatement
id value acc_no adate
---------------------------------------------
1 12 1 2019-01-01 07:40:38.250
2 14 1 2019-01-02 07:41:05.883
3 15 1 2019-01-13 07:41:22.377
4 10 2 2019-01-14 08:15:53.403
5 16 2 2019-01-03 13:52:47.347
6 19 1 2019-01-09 13:53:56.317
7 7 3 2019-01-17 00:00:00.000
8 24 2 2019-01-17 00:00:00.000
9 19 2 2019-01-02 00:00:00.000
10 7 1 2019-01-07 00:00:00.000
11 24 1 2019-01-05 14:12:47.080
12 20 3 2019-01-28 00:00:00.000
预期结果
id value acc_no aDATE result
------------------------------------------------------------------------
1 12 1 2019-01-01 07:40:38.250 12 (current row values of acc_no=1)
2 14 1 2019-01-02 07:41:05.883 2 (14 (current row values)-12(previous row value of acc_no=1))
11 24 1 2019-01-05 14:12:47.080 10 (24 (current row values)-14(previous date value of acc_no=1))
10 7 1 2019-01-07 00:00:00.000 -17 (7 (current row values)-24(previous date value of acc_no=1))
6 19 1 2019-01-09 13:53:56.317 12 (19 (current row values)-7(previous date value of acc_no=1))
3 15 1 2019-01-13 07:41:22.377 -4 (15 (current row values)-19(previous date value of acc_no=1))
9 19 2 2019-01-02 00:00:00.000 19 (12 (current row values of acc_no=2)
5 16 2 2019-01-03 13:52:47.347 -3 (16 (current row values)-14(previous date value of acc_no=2))
4 10 2 2019-01-14 08:15:53.403 -6 (10 (current row values)-16(previous date value of acc_no=2))
8 24 2 2019-01-17 00:00:00.000 14 (24 (current row values)-10(previous date value of acc_no=2))
7 7 3 2019-01-17 00:00:00.000 7 (12(current row values of acc_no=3)
12 20 3 2019-01-28 00:00:00.000 13 (20 (current row values)-7(previous date value of acc_no=3))
我尝试了以下查询
SELECT
id, t.value, acc_no, adate,
t.value - ISNULL(v.value, 0) AS result
FROM
TB_DailyStatementt
OUTER APPLY
(SELECT TOP (1) value
FROM TB_DailyStatement
WHERE id < t.id
AND acc_no = t.acc_no
ORDER by id DESC) v
这将返回一些输出,但是我无法使用order by子句,即adate和acc_no
如果您想通过acc_no asc简单地得到此结果,则可以得到简单的预期结果,
例如
从表顺序中按acc_no acs选择*
在SQL Server 2008
,不能使用LEAD & LAG
,为此,您可以像使用OUTER APPLY
一样使用查询。
select *
from TB_DailyStatementt tout
outer apply (select top 1 value Prev
from TB_DailyStatementt t1
where t1.acc_no = tout.acc_no
AND t1.adate < tout.adate
order by t1.adate desc)t1
outer apply (select top 1 value Next
from TB_DailyStatementt t1
where t1.acc_no = tout.acc_no
AND t1.adate > tout.adate
order by t1.adate asc)t2
order by tout.adate,acc_no
这将根据acc_no提供所需的上一个和下一个值。 现在,您可以应用开关大小写来格式化字符串。
检查这个演示
Declare @ds TABLE (id int, value int, acc_no int, dt datetime)
INSERT INTO @ds
SELECT 1, 12, 1, '2019-01-01 07:40:38.250' UNION
SELECT 2, 14, 1, '2019-01-02 07:41:05.883' UNION
SELECT 3, 15, 1, '2019-01-13 07:41:22.377' UNION
SELECT 4, 10, 2, '2019-01-14 08:15:53.403' UNION
SELECT 5, 16, 2, '2019-01-03 13:52:47.347' UNION
SELECT 6, 19, 1, '2019-01-09 13:53:56.317' UNION
SELECT 7, 7, 3, '2019-01-17 00:00:00.000' UNION
SELECT 8, 24, 2, '2019-01-17 00:00:00.000' UNION
SELECT 9, 19, 2, '2019-01-02 00:00:00.000' UNION
SELECT 10, 7, 1, '2019-01-07 00:00:00.000' UNION
SELECT 11, 24, 1, '2019-01-05 14:12:47.080' UNION
SELECT 12, 20, 3, '2019-01-28 00:00:00.000'
SELECT id, value, acc_no, dt, value - previous AS result
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY DS1.id
ORDER BY DS2.dt DESC) AS rn
,DS1.*, COALESCE(DS2.value,0) AS previous
FROM @ds DS1
LEFT JOIN @ds DS2
ON DS2.acc_no = DS1.acc_no
AND DS2.dt < DS1.dt
) AS dt
WHERE rn = 1
在原始查询中,您加入了ID,在所需结果中的注释表明您要使用订购日期,而不是ID。
因此,您可以通过将“ id <t.id”更改为“ adate <t.adate”来解决原始查询
我认为您在正确的轨道上。 您需要在外部查询中使用order by
并修复表别名:
SELECT ds.id, ds.value, ds.acc_no, ds.adate,
(t.value - COALESCE(prev.value, 0)) AS result
FROM TB_DailyStatementt ds OUTER APPLY
(SELECT TOP (1) ds2.value
FROM TB_DailyStatement ds2
WHERE ds2.id < ds.t.id AND ds2.acc_no = ds.acc_no
ORDER by ds2.id DESC
) prev
ORDER BY ds.acc_no, ds.adate
尝试这个:
Select *, CASE WHEN LAG(value) OVER(partition by acc_no order by adate) IS NULL THEN value
ELSE value - LAG(value) OVER(partition by acc_no order by adate) END result from TB_DailyStatement
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.