我已经为我正在处理的仓库实施了四个 SCD,它们正在工作。希望我已经正确理解了 SCD 方法,并且假设我已经理解了,我现在有一些问题需要帮助。
问题是有些字段可以更新而无需创建新维度,因为它们与时间无关。所以在 MERGE 语句中,我想要两个语句:
WHEN MATCHED AND tgt.HashBytes_Value <> src.HashBytes_Value
THEN
UPDATE Row_Expiry_Details
WHEN MATCHED AND tgt.HashBytes_Value = src.HashBytes_Value
THEN
UPDATE Columns_That_Are_Not_SCD_Relevant
etc..
我不确定如何在查询中添加第二个 WHEN MATCHED。
这是一个现在运行良好但没有做我想要的代码的示例。
-- Created temp tables for example
DROP TABLE IF EXISTS #StagingTable
CREATE TABLE #StagingTable
(
id INT,
name VARCHAR(20),
team VARCHAR(20),
preferences VARCHAR(50),
hashbytes_Value VARBINARY(20)
)
DROP TABLE IF EXISTS #PresTable
CREATE TABLE #PresTable
(
dim_id INT IDENTITY(1,1) PRIMARY KEY,
id INT,
name VARCHAR(20),
team VARCHAR(20),
preferences VARCHAR(50),
hashbytes_Value VARBINARY(20),
row_Current_ind BIT DEFAULT(1),
row_effective_date DATETIME2 DEFAULT(SYSDATETIME()),
row_expiry_date DATETIME2 DEFAULT(SYSDATETIME())
)
-- Load Staging
insert into #StagingTable (id, name, team, preferences, hashbytes_Value)
select id = 1, name = 'archibald', team = 'team 1', preferences = 'Throwaway String', hashbytes_value = hashbytes('sha1', (select team = 'team 1', name = 'archibald' for xml raw))
union select id = 2, name = 'dave', team = 'team 1', preferences = 'Throwaway String', hashbytes_value = hashbytes('sha1', (select team = 'team 1', name = 'dave' for xml raw))
union select id = 3, name = 'peter', team = 'team 2', preferences = 'Throwaway String', hashbytes_value = hashbytes('sha1', (select team = 'team 2', name = 'peter' for xml raw))
union select id = 4, name = 'roger', team = 'team 2', preferences = 'Throwaway String', hashbytes_value = hashbytes('sha1', (select team = 'team 2', name = 'roger' for xml raw))
-- scd merge
insert into #PresTable (id, name, team, preferences, hashbytes_Value)
select id, name, team, preferences, hashbytes_Value
from
(
merge into #PresTable as tgt
using
(
select
id
,name
,team
,preferences
,hashbytes_value
from
#StagingTable
) as src
-- alias
(id, name, team, preferences, hashbytes_Value)
on src.id = tgt.id
-- must be most recent row
and tgt.row_current_ind = 1
when matched
and tgt.hashbytes_value <> src.hashbytes_value
then
update
set
tgt.row_current_ind = 0
,row_expiry_date = sysdatetime()
when not matched
then
insert
(
id
,name
,team
,preferences
,hashbytes_Value
)
values
(
src.id
,src.name
,src.team
,src.preferences
,src.hashbytes_value
)
output
$action
,src.id
,src.name
,src.team
,src.preferences
,src.hashbytes_value
)
as changes
(
action
,id
,name
,team
,preferences
,hashbytes_Value
) where action = 'update'
truncate table #StagingTable
insert into #StagingTable (id, name, team, preferences, hashbytes_Value)
select id = 1, name = 'archibald', team = 'team 1', preferences = 'Updated Throwaway String', hashbytes_value = hashbytes('sha1', (select team = 'team 1', name = 'archibald' for xml raw))
union select id = 3, name = 'peter', team = 'team 1', preferences = 'Updated Throwaway String', hashbytes_value = hashbytes('sha1', (select team = 'team 1', name = 'peter' for xml raw))
union select id = 5, name = 'russell', team = 'team 2', preferences = 'Updated Throwaway String', hashbytes_value = hashbytes('sha1', (select team = 'team 2', name = 'roger' for xml raw))
-- scd merge
insert into #PresTable (id, name, team, preferences, hashbytes_Value)
select id, name, team, preferences, hashbytes_Value
from
(
merge into #PresTable as tgt
using
(
select
id
,name
,team
,preferences
,hashbytes_value
from
#StagingTable
) as src
-- alias
(id, name, team, preferences, hashbytes_Value)
on src.id = tgt.id
-- must be most recent row
and tgt.row_current_ind = 1
when matched
and tgt.hashbytes_value <> src.hashbytes_value
then
update
set
tgt.row_current_ind = 0
,row_expiry_date = sysdatetime()
when not matched
then
insert
(
id
,name
,team
,preferences
,hashbytes_Value
)
values
(
src.id
,src.name
,src.team
,src.preferences
,src.hashbytes_value
)
output
$action
,src.id
,src.name
,src.team
,src.preferences
,src.hashbytes_value
)
as changes
(
action
,id
,name
,team
,preferences
,hashbytes_Value
) where action = 'update'
select * from #PresTable
最终输出应该如您所见,但首选项应该是“更新的一次性字符串”,其中 id = 1。
这可能在同一个合并语句中吗?还是在运行合并语句之前/之后需要更新?
帖子由某人编辑,但这是我最后想看到的示例:
UPDATE TGT
SET
TGT.preferences = SRC.preferences
FROM
#PresTable TGT
INNER JOIN
#StagingTable SRC
ON SRC.id = TGT.id
WHERE 1=1
AND TGT.hashbytes_Value = SRC.hashbytes_Value
select * from #PresTable
谢谢你。