如何使用system-versioned temporal table获取指定列的最后更新时间
使用系统版本时态表查询指定列最后更新时间的方案
核心思路
系统版本时态表会完整留存每行每次变更的历史版本,我们只需要对比同一行相邻历史版本的目标列值,就能定位到目标列最近一次发生变更的时间点,无需额外维护自定义字段或触发器。
该方案可直接复用查询任意列的最后更新时间,替换代码中的列名即可,适配你提到的A、B、C三列独立更新的场景。
常用查询实现
1. 单行查询(查询指定主键行的B列最后更新时间)
假设你的时态表名为YourTable,主键为ID,系统默认周期字段为SysStartTime(行版本生效时间)、SysEndTime(行版本失效时间):
SELECT TOP 1 SysStartTime AS B_LastUpdatedTime FROM YourTable FOR SYSTEM_TIME ALL WHERE ID = @TargetRowID -- 替换为你要查询的行的主键值 -- 列允许NULL值的话替换为下方的判断条件 -- AND (B <> LAG(B) OVER (PARTITION BY ID ORDER BY SysStartTime) OR (B IS NULL <> LAG(B) OVER (PARTITION BY ID ORDER BY SysStartTime) IS NULL)) AND B <> LAG(B) OVER (PARTITION BY ID ORDER BY SysStartTime) ORDER BY SysStartTime DESC;
2. 批量查询(查询全表所有行的B列最后更新时间)
WITH RowVersions AS ( SELECT ID, B, SysStartTime, LAG(B) OVER (PARTITION BY ID ORDER BY SysStartTime) AS Prev_B FROM YourTable FOR SYSTEM_TIME ALL ), ColumnChanges AS ( SELECT ID, MAX(SysStartTime) AS B_LastUpdatedTime FROM RowVersions -- 同样支持NULL值判断,按需替换条件即可 WHERE B <> Prev_B GROUP BY ID ) -- 从未更新过B列的行,返回行创建时间作为最后更新时间 SELECT t.ID, t.B, ISNULL(c.B_LastUpdatedTime, t.SysStartTime) AS B_LastUpdatedTime FROM YourTable t LEFT JOIN ColumnChanges c ON t.ID = c.ID;
优化建议
如果历史版本数据量较大,可以给表新增(ID, SysStartTime)组合索引,能大幅降低窗口函数的排序开销,提升查询速度。
内容的提问来源于stack exchange,提问作者Tomi
相关产品推荐
相关产品推荐

