我有一个包含多个列的源表A.我想将源表转换为目标表。我希望有一个映射表,其列与源表A相同,并且包含构成转换的行。
以下是表A的示例:
COL1 COL2 COL3
aktie ja 2
aktie nej 3
obli ja 2
这是映射表
COL1 COL2 COL3 TRANSFORM
aktie ja NULL 3
aktie NULL NULL 4
现在,我们的想法是将源表与映射连接起来并获取返回的转换值。 NULL的使用应该用作通配符。所以我想要的结果应该是表A中的第一行与映射表中的第一行匹配并返回值3
对于第二行 - 这是我的挑战 - 我希望它匹配映射表中的第二行,因为它不匹配已经有值的行(这将导致转换后的值3)和as第二列中的第二个映射行为NULL,应将其视为通配符(尽管也考虑了映射表中的其他行)。
我的第一次尝试就像是
select A.*, m.res
from tab1 A
inner join mapping m on t.col1 = isnull(m.col1, t.col1)
and t.col2 = isnull(m.col2, t.col2)
and ...
但问题是isnull(..,..)
将匹配所有内容,而不仅仅返回匹配项,但列出的可能值会导致不同的转换。
我正在寻找适用于任何列数的通用解决方案,而不仅仅是这里提到的特定表格布局。
我一直在考虑这个问题并且似乎无法提出解决方案,所以请帮助:)
答案 0 :(得分:0)
以下是使用CTE执行此操作的一种方法(可在SQL Server和Oracle上使用)
WITH Map3 as
( -- TRANSFORM WILL BE NULL IF A MATCH WAS NOT MADE
SELECT T1.COL1, T1.COL2, T1.COL3, M.TRANSFORM
FROM Table1 T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = M.COL2
AND T1.COL3 = COALESCE(M.COL3, T1.COL3)
), Map2 as
(
SELECT T1.COL1, T1.COL2, T1.COL3, COALESCE(T1.TRANSFORM,M.TRANSFORM)
FROM Map3 T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = COALESCE(M.COL2, T1.COL2)
AND T1.TRANSFORM IS NULL
)
SELECT *
FROM Map2
我相信很明显这是如何运作的,以及如何延伸"这更多列。
如果您不能使用CTE,这在功能上是相同的,可以根据您的喜好嵌套:
SELECT T1.COL1, T1.COL2, T1.COL3, COALESCE(T1.TRANSFORM,M.TRANSFORM)
FROM (
-- TRANSFORM WILL BE NULL IF A MATCH WAS NOT MADE
SELECT T1.COL1, T1.COL2, T1.COL3, M.TRANSFORM
FROM Table1 T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = M.COL2
AND T1.COL3 = COALESCE(M.COL3, T1.COL3)
) T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = COALESCE(M.COL2, T1.COL2)
AND T1.TRANSFORM IS NULL