实际上 Table 中的重复行来自维度中的 SCD2 更改
Duplicate Rows in Fact Table from SCD2 changes in Dimension
好的,下面是简化的 tables 以帮助解释我的情况
已创建事实清单:
ListingCreatedSk
CreatedDateSk
ListingSk
StateSk
DimListing
ListingSk
ListingBk
StateCode
ListingPrice (SCD2)
ListingStatus (SCD2)
RowEffectiveDate
RowExpirationDate
RowCurrentIndicator
我遇到的问题是,当我将更新从我的维度合并到我的基本事务事实时 table 由于维度添加新行。处理这些情况的最佳方法是什么,我们拥有的关键约束是我们希望事实中的每一行都指向维度 table.
中的原始 Sk
当前程序:
MERGE INTO dbo.FactListingCreated AS target
USING
(
SELECT dlm.CreatedDateSk,
dl.ListingSk,
CASE
WHEN db.BrokerageSk IS NULL THEN -1
ELSE db.BrokerageSk
END as BrokerageSk,
ds.StateSk
FROM stage.DimListingMerge as dlm
LEFT JOIN dbo.DimDate as dd
ON dd.DateSk = dlm.CreatedDateSk
LEFT JOIN dbo.DimListing as dl
ON dl.ListingBk = dlm.ListingBk
AND dl.RowCurrentIndicator = 1
LEFT JOIN dbo.DimBrokerage as db
ON db.BrokerageBk = dlm.BrokerageBk
LEFT JOIN dbo.DimState as ds
ON ds.StateCode = dlm.StateCode
) source
ON (target.ListingSk = source.ListingSk)
THEN UPDATE SET
target.CreatedDateSk = source.CreatedDateSk,
target.BrokerageSk = source.BrokerageSk,
target.StateSk = source.StateSk
WHEN NOT MATCHED THEN
INSERT VALUES
(
source.CreatedDateSk,
source.ListingSk,
source.StateSk
);
所以我认为这个过程适用于更新(只提取前一天的数据),但是,最好的方法是制作一个单独的初始 运行(从 dim 中提取所有数据)它在哪里拉出每条记录的初始行?还是我遗漏了一些非常明显的东西,可以通过单个存储过程实现这一点?
当您加载引用 SCD2 维度的事实 table 时,您需要 select 维度记录,来自许多具有相同 BK 且在事实发生时适用的维度记录“事件”日期 - 该事件日期对于您的事实而言是由您的业务逻辑决定的,因此它可能是创建日期、生效日期或其他日期。假设它是一个名为 EventDate 的列...
您的 SQL JOIN 需要如下所示:
LEFT JOIN dbo.DimListing as dl
ON dl.ListingBk = dlm.ListingBk
AND dlm.EventDate BETWEEN dl.RowEffectiveDate AND dl.RowExpirationDate
目前,您的 SQL 只是从所有事实记录的维度中选取当前行,因此,我怀疑,这就是您获得重复项的原因
好的,下面是简化的 tables 以帮助解释我的情况
已创建事实清单:
ListingCreatedSk
CreatedDateSk
ListingSk
StateSk
DimListing
ListingSk
ListingBk
StateCode
ListingPrice (SCD2)
ListingStatus (SCD2)
RowEffectiveDate
RowExpirationDate
RowCurrentIndicator
我遇到的问题是,当我将更新从我的维度合并到我的基本事务事实时 table 由于维度添加新行。处理这些情况的最佳方法是什么,我们拥有的关键约束是我们希望事实中的每一行都指向维度 table.
中的原始 Sk当前程序:
MERGE INTO dbo.FactListingCreated AS target
USING
(
SELECT dlm.CreatedDateSk,
dl.ListingSk,
CASE
WHEN db.BrokerageSk IS NULL THEN -1
ELSE db.BrokerageSk
END as BrokerageSk,
ds.StateSk
FROM stage.DimListingMerge as dlm
LEFT JOIN dbo.DimDate as dd
ON dd.DateSk = dlm.CreatedDateSk
LEFT JOIN dbo.DimListing as dl
ON dl.ListingBk = dlm.ListingBk
AND dl.RowCurrentIndicator = 1
LEFT JOIN dbo.DimBrokerage as db
ON db.BrokerageBk = dlm.BrokerageBk
LEFT JOIN dbo.DimState as ds
ON ds.StateCode = dlm.StateCode
) source
ON (target.ListingSk = source.ListingSk)
THEN UPDATE SET
target.CreatedDateSk = source.CreatedDateSk,
target.BrokerageSk = source.BrokerageSk,
target.StateSk = source.StateSk
WHEN NOT MATCHED THEN
INSERT VALUES
(
source.CreatedDateSk,
source.ListingSk,
source.StateSk
);
所以我认为这个过程适用于更新(只提取前一天的数据),但是,最好的方法是制作一个单独的初始 运行(从 dim 中提取所有数据)它在哪里拉出每条记录的初始行?还是我遗漏了一些非常明显的东西,可以通过单个存储过程实现这一点?
当您加载引用 SCD2 维度的事实 table 时,您需要 select 维度记录,来自许多具有相同 BK 且在事实发生时适用的维度记录“事件”日期 - 该事件日期对于您的事实而言是由您的业务逻辑决定的,因此它可能是创建日期、生效日期或其他日期。假设它是一个名为 EventDate 的列...
您的 SQL JOIN 需要如下所示:
LEFT JOIN dbo.DimListing as dl
ON dl.ListingBk = dlm.ListingBk
AND dlm.EventDate BETWEEN dl.RowEffectiveDate AND dl.RowExpirationDate
目前,您的 SQL 只是从所有事实记录的维度中选取当前行,因此,我怀疑,这就是您获得重复项的原因