实时加入 SQL 时态表

问题描述 投票:0回答:2

我正在尝试执行以下操作:

SELECT report.*,
doc.*
FROM report
FOR system_time ALL report
JOIN Document
FOR system_time as of <<report.BeginDate>> doc ON report.DocumentId = doc.DocumentId

基本上我想获取父表的所有历史记录,以及根据父行在正确时间关联的子表。这可能吗?

sql sql-server temporal-tables
2个回答
7
投票

不幸的是,

FOR SYSTEM_TIME
仅允许文字或变量/参数。它不能是查询中的列。但是您可以将其放入内联表值函数中,然后
APPLY
该函数:

CREATE OR ALTER FUNCTION dbo.DocumentAsOfDate (@documentId int, @asOfDate datetime(7))
RETURNS TABLE
AS RETURN
SELECT d.*
FROM dbo.Document FOR SYSTEM_TIME AS OF @asOfDate AS d
WHERE d.DocumentId = @documentId;

GO
SELECT
  report.*,
  doc.*
FROM report FOR SYSTEM_TIME ALL report
CROSS APPLY dbo.DocumentAsOfDate (report.DocumentId, report.BeginDate) doc;

您可能需要考虑使用哪个日期(开始或结束),以及是否使用

FOR SYSTEM_TIME BETWEEN...
或其他过滤器。


0
投票

这些都是有趣的解决方案,但它们确实没有回答一般问题。如何在 TSQL 中编写临时连接?如果微软能提供一些这方面的文档就好了,但他们没有。

关键是FOR system_time ALL返回所有组合。您需要外连接,因为一侧或另一侧可能在任何给定时间点缺少值。现在你要处理两个条件。一个在另一个的开始和结束之间开始,反之亦然。

为了获得额外的分数,请删除 For System_Time All 并将查询放入视图中。当在没有系统时间的情况下调用视图时(或指定日期时),仅返回截至该时间的状态。当使用任何其他选项时,将返回相应的行。行可能从连接的一侧或另一侧返回。

我还没有完全测试过这个,可能有我没有想到的场景。

这是我的解决方案:

SELECT report.*, doc.*, 
    Greatest(report.[SysStart], doc.[SysStart]) As [SysStart],
    Least(report.[SysEnd], doc.[SysEnd]) As [SysEnd],
FROM report FOR system_time ALL report
JOIN Document FOR system_time ALL doc
ON report.DocumentId = doc.DocumentId AND
((report.[SysStart] >= doc.[SysStart] AND report.[SysStart] < doc.[SysEnd]) OR
 (doc.[SysStart] >= report.[SysStart] And doc.[SysStart] < report.[SysEnd]))

 -- Step Two, make it a View that accepts For System_Time
  Create View [TemporalJoin] As
 SELECT report.*, doc.*, 
    Greatest(report.[SysStart], doc.[SysStart]) As [SysStart],
    Least(report.[SysEnd], doc.[SysEnd]) As [SysEnd],
FROM [report]
JOIN [Document] doc
ON report.DocumentId = doc.DocumentId AND
((report.[SysStart] >= doc.[SysStart] AND report.[SysStart] < doc.[SysEnd]) OR
 (doc.[SysStart] >= report.[SysStart] And doc.[SysStart] < report.[SysEnd]))
© www.soinside.com 2019 - 2024. All rights reserved.