假设我的来源看起来像
X1 H_ID l1_no l2_no l3_no
20 1 2 12 42
20 1 6 16 42
20 1 1 19 41
20 1 5 15 41
我的查找表看起来像
X1 H_ID l1_no l1_key l2_no l2_key l3_no l3_key
20 1 4 104 14 114 44 144
20 1 3 103 13 113 43 143
20 1 1 101 11 111 41 141
20 1 2 102 12 112 42 142
在这种情况下,只有当我有一个完全匹配并且完整的键将被保留时,我的记录才被视为更新。如果它与任何列都不匹配,则将其视为插入。棘手的部分甚至是插入,必须检查每个层次结构级别,并且必须保留键以匹配位。
例如假设我已经有 1->11->14 并且我验证了 1->11->15 那么这必须是一个插入记录但必须保留 1 和 11 的键并且必须生成 15
此外,如果我得到 1->12->14,那么在这种情况下,记录将被视为插入,并且必须仅为 1 保留密钥,并且必须为 12 和 14 生成新密钥
我能想到的一种可能的解决方案是通过将数据集视为二维矩阵来对每个级别进行左连接。但这不是一个很好的方法。
WITH lookup ( x1, h_id, l1_no, l1_key, l2_no, l2_key,l3_no,l3_key ) AS
(SELECT 20, 1, 1, 101, 11, 111, 41, 141 FROM sys.dual UNION ALL
SELECT 20, 1, 2, 102, 12, 112, 42, 142 FROM sys.dual UNION ALL
SELECT 20, 1, 3, 103, 13, 113, 43, 143 FROM sys.dual UNION ALL
SELECT 20, 1, 4, 104, 14, 114, 44, 144 FROM sys.dual),
dwh_keys AS
(SELECT x1, h_id, MAX(l1_key) mk1, MAX(l2_key) mk2, MAX(l3_key) mk3
FROM lookup GROUP BY 1,2) ,
src ( x1, h_id, l1_no, l2_no, l3_no ) AS
(SELECT 20, 1, 1, 19, 41 FROM sys.dual UNION ALL
SELECT 20, 1, 2, 12, 42 FROM sys.dual UNION ALL
SELECT 20, 1, 5, 15, 41 FROM sys.dual UNION ALL
SELECT 20, 1, 6, 16, 42 FROM sys.dual),
stg1 AS
(SELECT b.*,
CASE WHEN a.x1 IS NOT NULL THEN 'U' ELSE 'I' END AS delta_type
FROM src b LEFT OUTER JOIN lookup a ON a.x1 = b.x1 AND a.h_id = b.h_id
AND a.l1_no = b.l1_no AND a.l2_no = b.l2_no AND a.l3_no = b.l3_no)
SELECT a.*,
CASE WHEN delta_type = 'I' AND b.l1_no IS NULL THEN mk1 + ROW_NUMBER ( ) OVER (ORDER BY delta_type) ELSE b.l1_key END AS new1_key,
CASE WHEN delta_type = 'I' AND c.l2_no IS NULL THEN mk2 + ROW_NUMBER ( ) OVER (ORDER BY delta_type) ELSE c.l2_key END AS new1_key,
CASE WHEN delta_type = 'I' AND d.l3_no IS NULL THEN mk3 + ROW_NUMBER ( ) OVER (ORDER BY delta_type) ELSE d.l3_key END AS new1_key,
delta_type
FROM stg1 a
LEFT OUTER JOIN lookup b ON a.x1 = b.x1 AND a.h_id = b.h_id AND a.l1_no = b.l1_no
LEFT OUTER JOIN lookup c ON a.x1 = c.x1 AND a.h_id = c.h_id AND a.l1_no = c.l1_no AND a.l2_no = c.l2_no
LEFT OUTER JOIN lookup d ON a.x1 = d.x1 AND a.h_id = d.h_id AND a.l1_no = d.l1_no AND a.l2_no = d.l2_no AND a.l3_no = d.l3_no
LEFT OUTER JOIN dwh_keys xx ON a.x1 = xx.x1 AND a.h_id = xx.h_id;
我得到的输出(也是我想要的)
X1 H_ID L1_NO L2_NO L3_NO DELTA_TYPE NEW1_KEY NEW1_KEY NEW1_KEY DELTA_TYPE
20 1 6 16 42 I 105 115 145 I
20 1 5 15 41 I 106 116 146 I
20 1 1 19 41 I 101 117 147 I
20 1 2 12 42 U 102 112 142 U
我的数据库WX2
不支持递归 CTE,我所拥有的只是简单的 ANSI SQL 语法,但递归 CTE 除外。