如何编写使用通配符映射进行转换的SQL查询

时间:2015-05-12 19:13:45

标签: sql wildcard

我有一个包含多个列的源表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(..,..)将匹配所有内容,而不仅仅返回匹配项,但列出的可能值会导致不同的转换。

我正在寻找适用于任何列数的通用解决方案,而不仅仅是这里提到的特定表格布局。

我一直在考虑这个问题并且似乎无法提出解决方案,所以请帮助:)

1 个答案:

答案 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