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

How to write an SQL query that uses wild-card map to do transformation

我有一个来源 table A 有很多列。我想将源 table 转换为目标 table。我想要一个映射 table,其列与源 table A 相同,行组成翻译。

这里是 table A:

的例子
COL1    COL2    COL3
aktie   ja         2
aktie   nej        3
obli    ja         2

这是映射 table

COL1    COL2    COL3        TRANSFORM
aktie   ja      NULL            3
aktie   NULL    NULL            4

现在,我们的想法是将源 table 与映射连接起来,并获得转换后的值 returned。 NULL 的使用应作为通配符。所以我想要的结果应该是 table A 中的第一行将匹配映射中的第一行 table 和 return 值 3

对于第二行 - 这是我的挑战 - 我希望它匹配映射中的第二行 table 因为它不匹配已经有值的行(这将导致转换值 3) 并且由于第二个映射行在第二列中有 NULL,因此应将其视为通配符(尽管也考虑了映射中的其他行 table)。

我的第一次尝试是这样的

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(..,..) 将匹配所有内容,而不仅仅是 return 匹配,但列出的可能导致不同转换的值除外。

我正在寻找一种通用解决方案,它适用于具有任意数量列的任何 table,而不仅仅是这里提到的这个特定的 table-layout。

我一直在思考这个问题,但似乎无法真正想出解决方案,所以请帮忙:)

这是使用 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

我相信它是如何工作的以及如何"extend"它到更多列。


如果您不能使用 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