时态表 - "Parameterise" 扩展 SYSTEM_TIME 语法
Temporal Tables - "Parameterise" extended SYSTEM_TIME syntax
SELECT *
FROM Spine S
CROSS
APPLY
(
SELECT *
FROM PersonTemporalTable
FOR SYSTEM_TIME AS OF S.DateTimeValueOfInterest
) CA
如果我省略其中的 "why" 并坚持使用 "what" 和 "how",会简单得多。
我需要能够在特定时间点查询 Temporal table 以获取记录状态 - 如果上述语法合法,它就会完全符合我的要求。
在这种情况下,table Spine 包含感兴趣的 DATETIME 值列表。
这仅仅是语法不正确的问题还是限制?
除了使用动态 SQL,你们还有其他我可以尝试的建议吗?
提前致谢!
这就是我根据@SQLZim
的建议着手做的
SELECT *
FROM Spine SP
JOIN PetTemporal FOR SYSTEM_TIME ALL PT ON SP.SpineDT >= PT.ValidFrom AND SP.SpineDT < PT.ValidTo
JOIN PersonTemporal FOR SYSTEM_TIME ALL PS ON SP.SpineDT >= PS.ValidFrom AND SP.SpineDT < PS.ValidTo
AND PS.PersonID = PT.PersonID
如果您想要 return Spine
行,即使 PersonTemporalTable
中没有相应的行,请切换到 outer apply()
.
如果PersonTemporalTable
包含有效日期范围:
select *
from Spine S
cross apply (
select ptt.*
from PersonTemporalTable
where ptt.FromDateTime <= S.DateTimeValueOfInterest
and ptt.ThruDateTime >= S.DateTimeValueOfInterest
) CA
如果PersonTemporalTable
包含一个生效日期:
select *
from Spine S
cross apply (
select top 1 ptt.*
from PersonTemporalTable ptt
where ptt.EffectiveDate <= S.DateTimeValueOfInterest
order by ptt.EffectiveDate desc
) CA
如果这应该是 return 行,其中两个 table 共享一个相应的键,例如PersonId
,然后将其包含在 cross apply()
的 where
中,例如:
select *
from Spine S
cross apply (
select top 1 ptt.*
from PersonTemporalTable ptt
where ptt.EffectiveDate <= S.DateTimeValueOfInterest
and ptt.PersonId = S.PersonId
order by ptt.EffectiveDate desc
) CA
另一个利用扩展 system_time as of
语法的选项:您可以创建一个内联 table 值函数来与 cross apply()
一起使用,如下所示:
create function dbo.PersonTemporalTable_AsOf (@fromdate datetime2(7)) returns table as return (
select *
from PersonTemporalTable
for system_time as of @fromdate
)
go
select *
from spine s
cross apply dbo.PersonTemporalTable_AsOf(s.DateTimeValueOfInterest) ca
dbfiddle.uk 演示:http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=f1ee20893fe987e71cbd0cb12d09fccb
SELECT *
FROM Spine S
CROSS
APPLY
(
SELECT *
FROM PersonTemporalTable
FOR SYSTEM_TIME AS OF S.DateTimeValueOfInterest
) CA
如果我省略其中的 "why" 并坚持使用 "what" 和 "how",会简单得多。 我需要能够在特定时间点查询 Temporal table 以获取记录状态 - 如果上述语法合法,它就会完全符合我的要求。 在这种情况下,table Spine 包含感兴趣的 DATETIME 值列表。
这仅仅是语法不正确的问题还是限制? 除了使用动态 SQL,你们还有其他我可以尝试的建议吗?
提前致谢!
这就是我根据@SQLZim
的建议着手做的SELECT *
FROM Spine SP
JOIN PetTemporal FOR SYSTEM_TIME ALL PT ON SP.SpineDT >= PT.ValidFrom AND SP.SpineDT < PT.ValidTo
JOIN PersonTemporal FOR SYSTEM_TIME ALL PS ON SP.SpineDT >= PS.ValidFrom AND SP.SpineDT < PS.ValidTo
AND PS.PersonID = PT.PersonID
如果您想要 return Spine
行,即使 PersonTemporalTable
中没有相应的行,请切换到 outer apply()
.
如果PersonTemporalTable
包含有效日期范围:
select *
from Spine S
cross apply (
select ptt.*
from PersonTemporalTable
where ptt.FromDateTime <= S.DateTimeValueOfInterest
and ptt.ThruDateTime >= S.DateTimeValueOfInterest
) CA
如果PersonTemporalTable
包含一个生效日期:
select *
from Spine S
cross apply (
select top 1 ptt.*
from PersonTemporalTable ptt
where ptt.EffectiveDate <= S.DateTimeValueOfInterest
order by ptt.EffectiveDate desc
) CA
如果这应该是 return 行,其中两个 table 共享一个相应的键,例如PersonId
,然后将其包含在 cross apply()
的 where
中,例如:
select *
from Spine S
cross apply (
select top 1 ptt.*
from PersonTemporalTable ptt
where ptt.EffectiveDate <= S.DateTimeValueOfInterest
and ptt.PersonId = S.PersonId
order by ptt.EffectiveDate desc
) CA
另一个利用扩展 system_time as of
语法的选项:您可以创建一个内联 table 值函数来与 cross apply()
一起使用,如下所示:
create function dbo.PersonTemporalTable_AsOf (@fromdate datetime2(7)) returns table as return (
select *
from PersonTemporalTable
for system_time as of @fromdate
)
go
select *
from spine s
cross apply dbo.PersonTemporalTable_AsOf(s.DateTimeValueOfInterest) ca
dbfiddle.uk 演示:http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=f1ee20893fe987e71cbd0cb12d09fccb