2

我正在尝试使用从以下网站获得的合并语句加载标准 Kimball SCD2 Dimension: http ://www.kimballgroup.com/2008/11/design-tip-107-using-the-sql-merge -声明用于缓慢变化的维度处理/

除了处理新实体之外,此合并语句是相同的。这将作为数据流中的直接插入处理。此问题仅涉及同一业务密钥的多个版本。

当我执行合并语句时,SQL 返回错误:

消息 8672,级别 16,状态 1,第 3 行
MERGE 语句多次尝试更新或删除同一行。当目标行匹配多个源行时会发生这种情况。
MERGE 语句不能多次 UPDATE/DELETE 目标表的同一行。优化 ON 子句以确保目标行最多匹配一个源行,或使用 GROUP BY 子句对源行进行分组。

我正在使用 SQL Server 2012:

源数据集

在此处输入图像描述

目标数据集

在此处输入图像描述

这是我所期望的:

在此处输入图像描述

您可以在下面找到重现问题的脚本:

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'

你能帮我解决这个问题吗?

4

1 回答 1

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
于 2016-11-21T10:48:55.147 回答