sql - 来自 SCD2 维度变化的事实表中的重复行
问题描述
好的,这里有一些简化的表格来帮助解释我的情况
事实清单创建:
ListingCreatedSk
CreatedDateSk
ListingSk
StateSk
昏暗列表
ListingSk
ListingBk
StateCode
ListingPrice (SCD2)
ListingStatus (SCD2)
RowEffectiveDate
RowExpirationDate
RowCurrentIndicator
我遇到的问题是,当我将维度中的更新合并到我的基本事务事实表时,由于维度中的 SCD2 更改添加了新行,我最终在我的事实中出现重复条目(相同的 ListingBK)。处理这些情况的最佳方法是什么,我们的关键约束是我们希望事实中的每一行都指向维度表中的原始 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
);
因此,我认为此过程适用于更新(仅提取前一天的数据),但是,最好的方法是进行单独的初始运行(从暗淡中提取所有数据),其中提取每条记录的初始行? 还是我错过了一些非常明显的东西,可以通过单个存储过程实现这一点?
解决方案
当您加载引用 SCD2 维度的事实表时,您需要从具有相同 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 只是从维度中获取所有事实记录的当前行,因此,我怀疑,您得到重复的原因
推荐阅读
- excel - 如何在带有空格的范围内查找第一个和最后一个填充的单元格
- f# - 忽略 F# 中的反斜杠和双引号
- numerical-methods - 如何解决常微分方程组解的数值不稳定性
- python - 根据索引将 Pandas DataFrame 中的行替换为其他 DataFrame
- excel - 如何比较Excel中两个单元格中的两个日期?
- azul-zulu - JDK 11 将根 ca 证书导入密钥库
- mysql - 同列同表不同条件查询
- r - R: pwfdtest (plm package) 产生错误信息
- c++ - 在另一个缓冲区创建调用之前,OpenCL 内核将无法工作
- laravel - Laravel 间歇性注销