【发布时间】:2021-08-18 15:25:47
【问题描述】:
我有一个合并语句,每晚都会构建我的 SCD 类型 2 表。该表必须包含在源系统中所做的所有历史更改,并创建一个新行,其中包含日期从/日期到列以及“islatest”标志。我今天遇到一个问题,我不确定如何处理。
在 24 小时内似乎对源表进行了多次更改。
ID Code PAN EnterDate Cost Created
16155 1012401593331 ENRD 2015-11-05 7706.3 2021-08-17 14:34
16155 1012401593331 ENRD 2015-11-05 8584.4 2021-08-17 16:33
我使用基本的合并语句来识别我的更改,但是确保正确获取所有更改的最佳方法是什么?上面给了我一个错误,因为它试图插入/更新具有相同值的多行
DECLARE @DateNow DATETIME = Getdate()
IF Object_id('tempdb..#meteridinsert') IS NOT NULL
DROP TABLE #meteridinsert;
CREATE TABLE #meteridinsert
(
meterid INT,
change VARCHAR(10)
);
MERGE
INTO [DIM].[Meters] AS target
using stg_meters AS source
ON target.[ID] = source.[ID]
AND target.latest=1
WHEN matched THEN
UPDATE
SET target.islatest = 0,
target.todate = @Datenow
WHEN NOT matched BY target THEN
INSERT
(
id,
code,
pan,
enterdate,
cost,
created,
[FromDate] ,
[ToDate] ,
[IsLatest]
)
VALUES
(
source.id,
source.code ,
source.pan ,
source.enterdate ,
source.cost ,
source.created ,
@Datenow ,
NULL ,
1
)
output source.id,
$action
INTO #meteridinsert;INSERT INTO [DIM].[Meters]
(
[id] ,
[code] ,
[pan] ,
[enterdate] ,
[cost] ,
[created] ,
[FromDate] ,
[ToDate] ,
[IsLatest]
)
SELECT ([id] ,[code] ,[pan] ,[enterdate] ,[cost] ,[created] , @DateNow ,NULL ,1 FROM stg_meters a
INNER JOIN #meteridinsert cid
ON a.id = cid.meterid
AND cid.change = 'UPDATE'
【问题讨论】:
-
为什么要使用
@datenow,如果你说同一个自然键有很多条记录要加载?您不需要用该自然键的下一条记录的startdate更新todate吗? -
我实际上是在遵循本指南,但我明白你在说什么(尤其是在这种情况下)使用下一条记录的开始日期purplefrogsystems.com/blog/2012/01/… 更有意义
标签: sql sql-server-2016