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

标签 sql sql-server t-sql

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

传出和传入值作为累积值而不是单个交易值存储在数据库中,但我正在寻找一种方法来选择 * 从此表并返回单个金额而不是累积值。

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

如果我在测试表中选择 where code = '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;

}

最佳答案

只需使用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];

关于sql - T-SQL 返回单个值而不是累积值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51772373/

相关文章:

mysql - where 子句不起作用 mysql

sql-server - 将 SQL Server 数据库分发为 .bak 或 .mdf 有何优点/缺点?

sql-server - SQL - 查找列属于哪个表的最佳方法是什么?

SQL Server 对行进行分组

sql-server - 仅与 Active Directory 建立连接...用户 '<token-identified principal>' 登录失败

c# - 如何在一笔交易中移动记录?或者 SQL 中的生产者-消费者模式

sql - 在 SQL 中正确使用 Count() 和 Sum() 吗?

mysql - 无法运行看似对其他人有效的 MySQL 代码

mysql - 每个id获取一个

sql - Erlang ODBC 连接挑战