【问题标题】:SQL Server : convert historical data to Temporal TablesSQL Server:将历史数据转换为临时表
【发布时间】:2017-05-02 20:15:22
【问题描述】:

我们拥有 SQL Server 2016。多年来,我们拥有自己的历史。现在我想将历史数据转换为新格式,并将 CustomAudit 表用作包含已有历史数据的历史表。

一开始会有一个小例子,然后是问题

CREATE TABLE [dbo].[client]
(
     idclient int identity(1,1) primary key, 
     clientData nvarchar (400)
) ON [PRIMARY] 

INSERT [dbo].[client] ( clientData ) values ('some-12221')
INSERT [dbo].[client] ( clientData ) values ('some-22111')

alter table [client] 
add 
    StartTime datetime2 GENERATED ALWAYS AS ROW START  DEFAULT GETUTCDATE(), 
    EndTime datetime2 GENERATED ALWAYS AS ROW END DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'), 
    PERIOD FOR SYSTEM_TIME (StartTime,EndTime) 

CREATE TABLE [dbo].[CustomAydit_client]
(
    idclient int,
    dEditDate datetime NOT NULL DEFAULT (getdate()), 
    clientData nvarchar (400)
) ON [PRIMARY] 

alter table [CustomAydit_client] 
add 
    StartTime datetime2 GENERATED ALWAYS AS ROW START  DEFAULT GETUTCDATE(), 
    EndTime datetime2 GENERATED ALWAYS AS ROW END DEFAULT CONVERT(DATETIME2, '9999-12-31 23:59:59.9999999'), 
    PERIOD FOR SYSTEM_TIME (StartTime,EndTime)

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (1, (CAST(N'2016-05-06 10:08:11.923' AS DateTime)), 'some-1')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (1, (CAST(N'2016-02-11 10:08:11.923' AS DateTime)), 'some-211')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (2, (CAST(N'2016-12-06 10:08:11.923' AS DateTime)), 'some-1')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (1, (CAST(N'2015-05-19 10:08:11.923' AS DateTime)), 'some-1')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (2, (CAST(N'2016-05-06 10:08:11.923' AS DateTime)), 'some-211')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData)
VALUES (1, (CAST(N'2016-05-26 10:08:11.923' AS DateTime)), 'some-1')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (2, (CAST(N'2016-05-06 10:08:11.923' AS DateTime)), 'some33-1')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (1, (CAST(N'2016-05-06 10:08:11.923' AS DateTime)), 'some3-1')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate,clientData) 
VALUES (2, (CAST(N'2016-11-16 10:08:11.923' AS DateTime)), 'some-1')

INSERT [dbo].[CustomAydit_client] (idclient, dEditDate, clientData) 
VALUES (1, (CAST(N'2016-02-17 10:08:11.923' AS DateTime)), 'some-1')

我需要行和行的 StartTime。

对于客户 1,我想获取字段 DeditDate 的第 2 行数据

更新此数据第 1 行字段 EndTime

最后一行,客户端不应该有 EndTime,这可以 9999-12-31 23:59:59.9999999

SELECT
    ROW_NUMBER() OVER( PARTITION BY idclient ORDER BY dEditDate) AS tempid,
    idclient,
    dEditDate,
    StartTime, EndTime
FROM
    [dbo].[CustomAydit_client]
ORDER BY
    idclient, dEditDate

【问题讨论】:

  • 您在发布表定义和示例数据方面做得很好。但我不太清楚你想要什么作为输出。
  • 在您需要 StartTime 和 EndTime 的行的临时表中。我不知道如何正确地完成 EndTime。使用我的数据
  • 不确定该图像应该向我显示什么。您的输出看起来与输入的数据相同。或者您是否试图使结束日期成为“下”行的开始日期值??

标签: sql sql-server sql-server-2016


【解决方案1】:

您可以使用lead 函数从下一行获取一个值作为结束时间。

select 
    ROW_NUMBER() OVER(PARTITION BY idclient ORDER BY dEditDate) AS tempid,
    idclient,
    dEditDate,
    StartTime,
    lead(dEditDate) over(PARTITION BY idclient ORDER BY dEditDate) as EndTime
from [dbo].[CustomAydit_client]
order by idclient, dEditDate

【讨论】:

  • 你对lead在很多行(超过100 mio)的情况下的性能有什么经验吗?
  • 谢谢你能帮我很多
  • @GoAnatol,你得到你的问题的答案了吗?我需要完全相同的东西
猜你喜欢
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 1970-01-01
相关资源
最近更新 更多