我正在尝试加载标准的Kimball SCD2 维度,使用我从以下网站获得的合并声明: http://www.kimballgroup.com/2008/11/design-tip-107-using-the-sql-merge-statement-for-slowly-changing-dimension-processing/
除了处理新实体之外,此合并语句是相同的。这将作为数据流中的直接插入处理。此问题仅涉及同一业务密钥的多个版本。
当我执行merge语句时,SQL返回错误:
Msg 8672,Level 16,State 1,Line 3
MERGE语句尝试多次更新或删除同一行。当目标行与多个源行匹配时会发生这种情况。
MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组。
我正在使用SQL Server 2012:
SOURCE DATASET
TARGET DATASET
这就是我的预期:
您可以在下面找到重现问题的脚本:
CREATE TABLE SANDBOX.EHN.SOURCE_SCD2 (
BUSINESS_KEY BIGINT
,DESCRIPTION_A VARCHAR(2)
,M_CRC BIGINT
,StartDATE DATE
,EndDATE DATE )
CREATE TABLE SANDBOX.EHN.TARGET_SCD2 (
BUSINESS_KEY BIGINT
,DESCRIPTION_A VARCHAR(2)
,M_CRC BIGINT
,StartDATE DATE
,EndDATE DATE )
select *
from SANDBOX.EHN.TARGET_SCD2
truncate table SANDBOX.EHN.TARGET_SCD2
INSERT INTO SANDBOX.EHN.SOURCE_SCD2 VALUES (1, 'B', 1, '2015-05-16', '2015-06-01')
INSERT INTO SANDBOX.EHN.SOURCE_SCD2 VALUES (1, 'C', 2, '2015-06-01', '2015-06-11')
INSERT INTO SANDBOX.EHN.SOURCE_SCD2 VALUES (1, 'D', 3, '2015-06-11', '9999-12-31')
INSERT INTO SANDBOX.EHN.TARGET_SCD2 VALUES (1, 'A', 0, '2015-01-16', '9999-12-31')
INSERT INTO SANDBOX.EHN.TARGET_SCD2
SELECT BUSINESS_KEY
,DESCRIPTION_A
,M_CRC
,StartDATE
,EndDATE
FROM (
MERGE SANDBOX.EHN.TARGET_SCD2 D
USING SANDBOX.EHN.SOURCE_SCD2 UPD
ON(D.BUSINESS_KEY = UPD.BUSINESS_KEY )
WHEN MATCHED AND D.EndDATE = '9999-12-31'
THEN UPDATE SET D.EndDATE = UPD.EndDATE
OUTPUT $Action Action_Out, UPD.BUSINESS_KEY
, UPD.DESCRIPTION_A
, UPD.M_CRC
, UPD.StartDATE
, UPD.EndDATE
)AS MERGE_OUT
WHERE MERGE_OUT.Action_Out = 'UPDATE'
你能帮我解决这个问题吗?
答案 0 :(得分:2)
对于上次更新,仅使用;
INSERT INTO SANDBOX.EHN.TARGET_SCD2
SELECT BUSINESS_KEY
,DESCRIPTION_A
,M_CRC
,StartDATE
,EndDATE
FROM (
MERGE SANDBOX.EHN.TARGET_SCD2 D
USING SANDBOX.EHN.SOURCE_SCD2 UPD
ON(D.BUSINESS_KEY = UPD.BUSINESS_KEY AND UPD.EndDATE = '9999-12-31')
WHEN MATCHED AND D.EndDATE = '9999-12-31'
THEN UPDATE SET D.EndDATE = UPD.StartDATE
OUTPUT $Action Action_Out, UPD.BUSINESS_KEY
, UPD.DESCRIPTION_A
, UPD.M_CRC
, UPD.StartDATE
, UPD.EndDATE
)AS MERGE_OUT
WHERE MERGE_OUT.Action_Out = 'UPDATE'
如果您想要目标表中的所有SRC行,那么我同意Nick.McDermaid
对于所有行使用;
UPDATE TRG
SET TRG.EndDate = SRC.StartDATE
FROM SANDBOX.EHN.TARGET_SCD2 TRG
JOIN ( select SRC.BUSINESS_KEY, min(src.StartDATE)StartDATE
from SANDBOX.EHN.SOURCE_SCD2 SRC
group by SRC.BUSINESS_KEY
)SRC
on ( TRG.BUSINESS_KEY = SRC.BUSINESS_KEY
AND SRC.StartDate > TRG.StartDate )
where 1 = 1
INSERT SANDBOX.EHN.TARGET_SCD2
SELECT * FROM SANDBOX.EHN.SOURCE_SCD2