T-SQL返回单个值,而不是累积值

时间:2018-08-09 16:57:02

标签: sql sql-server tsql

我在db中有一张表,该表存储了一段时间后各种帐户代码的传入,传出和净值。尽管有一个日期字段,但是每个帐户代码的事件顺序都是基于“版本”数字的,其中0 =每个帐户代码的原始记录,并且在每次更改该帐户代码后它都会增加1。

“支出”和“收入”值作为累积值而不是单个交易值存储在数据库中,但是我正在寻找一种方法,从该表中选择*并返回相对于累积值的单个金额。

下面是表和数据的测试脚本以及两个示例。

如果我在测试表中选择代码='123'的位置,则当前得到此信息(值是累积的);

+------+------------+---------+---------+---------+-----+
| Code |    Date    | Version | Incoming| Outgoing| Net |
+------+------------+---------+---------+---------+-----+
| 123  | 01/01/2018 |       0 |     100 |       0 | 100 |
| 123  | 07/01/2018 |       1 |     150 |       0 | 150 |
| 123  | 09/01/2018 |       2 |     150 |     100 |  50 |
| 123  | 14/01/2018 |       3 |     200 |     100 | 100 |
| 123  | 18/01/2018 |       4 |     200 |     175 |  25 |
| 123  | 23/01/2018 |       5 |     225 |     175 |  50 |
| 123  | 30/01/2018 |       6 |     225 |     225 |   0 |
+------+------------+---------+---------+---------+-----+

这是我希望看到的(每笔交易);

+------+------------+---------+----------+----------+------+
| Code |    Date    | Version | Incoming | Outgoing | Net  |
+------+------------+---------+----------+----------+------+
|  123 | 01/01/2018 |       0 |      100 |        0 |  100 |
|  123 | 07/01/2018 |       1 |       50 |        0 |   50 |
|  123 | 09/01/2018 |       2 |        0 |      100 | -100 |
|  123 | 14/01/2018 |       3 |       50 |        0 |   50 |
|  123 | 18/01/2018 |       4 |        0 |       75 |  -75 |
|  123 | 23/01/2018 |       5 |       25 |        0 |   25 |
|  123 | 30/01/2018 |       6 |        0 |       50 |  -50 |
+------+------------+---------+----------+----------+------+

如果我具有各个交易值并想报告累计金额,则可以使用OVER PARTITION BY,但这有相反的含义吗? 我不是要重新设计创建表或存储表的过程,而是想从我们的MI环境中报告这种情况。

注意:我在其中添加了其他随机帐户代码,以强调数据不是按代码或版本排序,而是按日期排序。

在此先感谢您的帮助。

USE [tempdb];

IF EXISTS ( SELECT  *
        FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_NAME = 'Table1'
        AND TABLE_SCHEMA = 'dbo')
DROP TABLE [dbo].[Table1];
GO

CREATE TABLE [dbo].[Table1]
(
 [Code] CHAR(3)
,[Date] DATE
,[Version] CHAR(3)
,[Incoming] DECIMAL(20,2)
,[Outgoing] DECIMAL(20,2)
,[Net] DECIMAL(20,2)
);
GO

INSERT INTO [dbo].[Table1] VALUES
('123','2018-01-01','0','100','0','100'),
('456','2018-01-02','0','50','0','50'),
('789','2018-01-03','0','0','0','0'),
('456','2018-01-04','1','100','0','100'),
('456','2018-01-05','2','150','0','150'),
('789','2018-01-06','1','50','50','0'),
('123','2018-01-07','1','150','0','150'),
('456','2018-01-08','3','200','0','200'),
('123','2018-01-09','2','150','100','50'),
('789','2018-01-10','2','0','0','0'),
('456','2018-01-11','4','225','0','225'),
('789','2018-01-12','3','75','25','50'),
('987','2018-01-13','0','0','50','-50'),
('123','2018-01-14','3','200','100','100'),
('654','2018-01-15','0','100','0','100'),
('456','2018-01-16','5','250','0','250'),
('987','2018-01-17','1','50','50','0'),
('123','2018-01-18','4','200','175','25'),
('789','2018-01-19','4','100','25','75'),
('987','2018-01-20','2','150','125','25'),
('321','2018-01-21','0','100','0','100'),
('654','2018-01-22','1','0','0','0'),
('123','2018-01-23','5','225','175','50'),
('321','2018-01-24','1','100','50','50'),
('789','2018-01-25','5','100','50','50'),
('987','2018-01-26','3','150','150','0'),
('456','2018-01-27','6','250','250','0'),
('456','2018-01-28','7','270','250','20'),
('321','2018-01-29','2','100','100','0'),
('123','2018-01-30','6','225','225','0'),
('987','2018-01-31','4','175','150','25')
;
GO

SELECT *
FROM [dbo].[Table1]
WHERE [Code] = '123'
GO;


USE [tempdb];

IF EXISTS ( SELECT  *
            FROM INFORMATION_SCHEMA.TABLES
            WHERE TABLE_NAME = 'Table1'
            AND TABLE_SCHEMA = 'dbo')
DROP TABLE [dbo].[Table1];
GO;

}

1 个答案:

答案 0 :(得分:2)

只需使用lag()

select Evt, Date, Version,
       (Loss - lag(Loss, 1, 0) over (partition by evt order by date)) as incoming,
       (Rec - lag(Rec, 1, 0) over (partition by evt order by date)) as outgoing,
       (Net - lag(Net, 1, 0) over (partition by evt order by date)) as net
from [dbo].[Table1];