我有一个名为STG
的源表,需要与名为MAP
的目标表“合并”。
STG
ID1 HASH TIME
A 123 12:01AM
A 456 12:05AM
A 789 12:10AM
B 123 12:15AM
B 789 12:20AM
C 987 12:25AM
MAP
ID1 ID2 HASH TIME
A A 123 11:55PM
ID1
中的 MAP
可以使用与STG
中相同的列值
ID2
的值由MAP
第一次看到ID1
和HASH
组合确定。例如,如果要将第4行B 123 12:15AM
作为单行插入MAP
,由于B A 123 12:15AM
值{{HASH
,因此它看起来像123
1}}已经在MAP
中,因此使用A
ID2
的现有值。
目标:将STG
中的所有行合并到MAP
中并使用相应的ID2
值。
例:
ID1
存在MAP
,HASH
存在MAP
:UPDATE(MAP.TIME = STG.TIME)
ID1
DNE MAP
,HASH
DNE MAP
:INSERT(STG.ID1, STG.ID1, STG.HASH, STG.TIME)
ID1
存在MAP
,HASH
DNE MAP
:INSERT(STG.ID1, MAP.ID2, STG.HASH, STG.TIME)
ID1
DNE MAP
,HASH
存在MAP
:INSERT(STG.ID1, MAP.ID2, STG.HASH, STG.TIME)
以这种方式解决问题的问题是STG
中的某些行彼此依赖。例如,我运行了执行Case 2的SQL代码,因为ID1
中不存在HASH
和MAP
,所以将插入第5行,但第4行与{ {1}}通过MAP
值HASH
。
案例1和案例2,是直截了当且显而易见的。在考虑依赖性的同时解决案例3和4已经证明是困难的。
如何解决案例3和案件4?
(正确的)最终结果应如下所示......
123
答案 0 :(得分:1)
你可以使用它。
DECLARE @STG TABLE (ID1 VARCHAR(5), [HASH] INT, [TIME] TIME)
INSERT INTO @STG VALUES
('A',123,'12:01AM'),
('A',456,'12:05AM'),
('A',789,'12:10AM'),
('B',123,'12:15AM'),
('B',789,'12:20AM'),
('C',987,'12:25AM')
DECLARE @MAP TABLE (ID1 VARCHAR(5), ID2 VARCHAR(5), [HASH] INT, [TIME] TIME)
INSERT INTO @MAP
VALUES
('A','A',123,'11:55PM')
;MERGE @MAP AS tar
USING (
SELECT S.ID1, COALESCE(M.ID1, S.ID1) ID2 , S.HASH, S.TIME
FROM @STG S
LEFT JOIN @MAP M ON (S.HASH = M.HASH OR S.ID1 = M.ID1)
) AS src (ID1, ID2, [HASH], [TIME])
ON (tar.ID1 = src.ID1 AND tar.[HASH] = src.[HASH])
WHEN MATCHED THEN
UPDATE SET [TIME] = src.[TIME]
WHEN NOT MATCHED THEN
INSERT (ID1, ID2, [HASH], [TIME])
VALUES (src.ID1, src.ID2, src.[HASH], src.[TIME]) ;
结果:
ID1 ID2 HASH TIME
----- ----- ----------- ----------------
A A 123 00:01:00.0000000
A A 456 00:05:00.0000000
A A 789 00:10:00.0000000
B A 123 00:15:00.0000000
B B 789 00:20:00.0000000
C C 987 00:25:00.0000000