如何使用 SQL 服务器(TSQL)根据前面的行值 change/version 历史记录生成记录
How to generate records based on preceding rows value change/version history using SQL Server (TSQL)
我有一个 table,我需要根据每天记录的插入和更新维护记录版本控制。 "RecordVersion" table 如下所示:
VersionID RecordID RecordValue DateID (FK Calendar)
--------- -------- ----------- ------
1 R1 50 1
2 R2 60 1
3 R3 100 2
4 R2 80 2
5 R3 150 5
6 R4 200 5
而 "Calendar" table 看起来像:
DateID Date
------ --------
1 1-May-19
2 2-May-19
3 3-May-19
4 4-May-19
5 5-May-19
6 6-May-19
如何填充 RecordVersion table:
- 2019 年 5 月 1 日,记录 R1 和 R2 已插入
- 2019 年 5 月 2 日,插入了新记录 R3 并更新了退出 R2(R1 保持不变)。因此,对于新的 "insert" 和 "update" 操作,都生成了新的版本号
- 2019 年 5 月 3 日和 2019 年 5 月 4 日未进行任何更改,未生成版本记录
- 2019 年 5 月 5 日,又出现了另一个新的 "Insert" 和 "Update",因此创建了两个版本
Output(VersionHistory) 应该如下所示:
DateID VersionID RecordID RecordValue
1 1 R1 50 --Initial Record
1 2 R2 60
2 1 R1 50 -- Non Versioned
2 4 R2 80 -- Versioned for Update (50>80)
2 3 R3 100 -- New Insert
3 1 R1 50 |
3 4 R2 80 --- No Change -- Just Replicate Prev.
3 3 R3 100 |
4 1 R1 50 |
4 4 R2 80 --- No Change -- Just Replicate Prev.
4 3 R3 100 |
5 1 R1 50 -- Non Versioned
5 4 R2 80 -- Non Versioned
5 5 R3 150 -- Versioned for Update (100>150)
5 6 R4 200 -- New Insert
如果有人可以使用 TSQL 生成上述输出,那就太好了。我的 SQLServer 版本是:
Microsoft SQL Azure (RTM) - 12.0.2000.8
这是我的初始数据:
DECLARE @RecordVersion TABLE (VersionID INT, RecordID VARCHAR(5), RecordValue INT, DateID INT);
INSERT INTO @RecordVersion(VersionID,RecordID,RecordValue,DateID)VALUES
(1,'R1',50,1)
,(2,'R2',60,1)
,(3,'R3',100,2)
,(4,'R2',80,2)
,(5,'R3',150,5)
,(6,'R4',200,5)
;
DECLARE @Calendar TABLE (DateID INT, [Date] DATE);
INSERT INTO @Calendar (DateID,[Date])VALUES
(1,'2019-05-01')
,(2,'2019-05-02')
,(3,'2019-05-03')
,(4,'2019-05-04')
,(5,'2019-05-05')
,(6,'2019-05-06')
;
代码:
SELECT b.DateID,b.VersionID,b.RecordID,b.RecordValue
FROM (
SELECT c.DateID,a.VersionID,a.RecordID,a.RecordValue
,ROW_NUMBER()OVER(PARTITION BY c.DateID,a.RecordID ORDER BY a.DateID DESC) AS [rn]
FROM @Calendar c
INNER JOIN (
SELECT v.DateID,d.[Date],v.VersionID,v.RecordID,v.RecordValue
FROM @RecordVersion v
INNER JOIN @Calendar d ON d.DateID = v.DateID
) a ON a.[Date] <= c.[Date]
) b
WHERE b.rn = 1
ORDER BY b.DateID,b.VersionID
;
不过它 returns 也是 6 号,不确定是否合适。请告诉我。
我有一个 table,我需要根据每天记录的插入和更新维护记录版本控制。 "RecordVersion" table 如下所示:
VersionID RecordID RecordValue DateID (FK Calendar)
--------- -------- ----------- ------
1 R1 50 1
2 R2 60 1
3 R3 100 2
4 R2 80 2
5 R3 150 5
6 R4 200 5
而 "Calendar" table 看起来像:
DateID Date
------ --------
1 1-May-19
2 2-May-19
3 3-May-19
4 4-May-19
5 5-May-19
6 6-May-19
如何填充 RecordVersion table:
- 2019 年 5 月 1 日,记录 R1 和 R2 已插入
- 2019 年 5 月 2 日,插入了新记录 R3 并更新了退出 R2(R1 保持不变)。因此,对于新的 "insert" 和 "update" 操作,都生成了新的版本号
- 2019 年 5 月 3 日和 2019 年 5 月 4 日未进行任何更改,未生成版本记录
- 2019 年 5 月 5 日,又出现了另一个新的 "Insert" 和 "Update",因此创建了两个版本
Output(VersionHistory) 应该如下所示:
DateID VersionID RecordID RecordValue
1 1 R1 50 --Initial Record
1 2 R2 60
2 1 R1 50 -- Non Versioned
2 4 R2 80 -- Versioned for Update (50>80)
2 3 R3 100 -- New Insert
3 1 R1 50 |
3 4 R2 80 --- No Change -- Just Replicate Prev.
3 3 R3 100 |
4 1 R1 50 |
4 4 R2 80 --- No Change -- Just Replicate Prev.
4 3 R3 100 |
5 1 R1 50 -- Non Versioned
5 4 R2 80 -- Non Versioned
5 5 R3 150 -- Versioned for Update (100>150)
5 6 R4 200 -- New Insert
如果有人可以使用 TSQL 生成上述输出,那就太好了。我的 SQLServer 版本是:
Microsoft SQL Azure (RTM) - 12.0.2000.8
这是我的初始数据:
DECLARE @RecordVersion TABLE (VersionID INT, RecordID VARCHAR(5), RecordValue INT, DateID INT);
INSERT INTO @RecordVersion(VersionID,RecordID,RecordValue,DateID)VALUES
(1,'R1',50,1)
,(2,'R2',60,1)
,(3,'R3',100,2)
,(4,'R2',80,2)
,(5,'R3',150,5)
,(6,'R4',200,5)
;
DECLARE @Calendar TABLE (DateID INT, [Date] DATE);
INSERT INTO @Calendar (DateID,[Date])VALUES
(1,'2019-05-01')
,(2,'2019-05-02')
,(3,'2019-05-03')
,(4,'2019-05-04')
,(5,'2019-05-05')
,(6,'2019-05-06')
;
代码:
SELECT b.DateID,b.VersionID,b.RecordID,b.RecordValue
FROM (
SELECT c.DateID,a.VersionID,a.RecordID,a.RecordValue
,ROW_NUMBER()OVER(PARTITION BY c.DateID,a.RecordID ORDER BY a.DateID DESC) AS [rn]
FROM @Calendar c
INNER JOIN (
SELECT v.DateID,d.[Date],v.VersionID,v.RecordID,v.RecordValue
FROM @RecordVersion v
INNER JOIN @Calendar d ON d.DateID = v.DateID
) a ON a.[Date] <= c.[Date]
) b
WHERE b.rn = 1
ORDER BY b.DateID,b.VersionID
;
不过它 returns 也是 6 号,不确定是否合适。请告诉我。