如何编写使用通配符映射进行转换的 SQL 查询 [英] How to write an SQL query that uses wild-card map to do transformation

查看:29
本文介绍了如何编写使用通配符映射进行转换的 SQL 查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含许多列的源表 A.我想将源表转换为目标表.我想要一个映射表,该表的列与源表 A 相同,行组成翻译.

I have a source table A with a number of columns. I want to do a transformation of the source table to a target table. I would like to have a mapping table with same columns as the source table A and with rows that make up the translations.

这是表 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

Now, the idea is to join the source table with the mapping and get the transformed value returned. The use of NULL should serve as a wildcard. So my desired result should be that the first row in table A would match the first row in the mapping table and return the value 3

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

For the second row - and here is my challenge - I want it to match the second row in the mapping table because it is NOT matched by rows that have a value already (which would result in the transformed value 3) and as the second mapping row has NULL in column two, it should be treated as a wildcard (although taking into account other rows in the mapping table as well).

我的第一次尝试是这样的

My first attempt would be something like

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(..,..) 将匹配所有内容,并且不仅返回匹配项,除了会导致不同转换的列出的可能值.

but the problem is that the isnull(..,..) will match everything and not only return matches except the listed possible values that would result in a different transformation.

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

I am looking for a generic solution that would Work for any table with any number of columns, not only this particular table-layout mentioned here.

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

I have been thinking a lot about this and cannot really seem to come up with the solution, so please help :)

推荐答案

这是一种使用 CTE 实现此目的的方法(适用于 SQL Server 和 Oracle)

Here is one way to do this using a CTE (will work on SQL Server and 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

我相信它的工作原理以及如何将其扩展"到更多列是很清楚的.

I believe it is clear how this works and how to "extend" this to more columns.

如果您不能使用 CTE,这在功能上是相同的,并且可以任意嵌套:

If you can't use a CTE this is functionally the same and can be nested as far as you like:

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

这篇关于如何编写使用通配符映射进行转换的 SQL 查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆