加入完全匹配值,否则加入默认值

时间:2016-01-18 19:42:45

标签: oracle join match

我有一张桌子

 c1   c2    c3    c4     value
all  all    all   all     5
all  david  all   Y       6
all  all    cd    all     7

和表b

c1   c2      c3     c4   
a   peter    cd      N    
b   david    all     Y     
c   all      cd      N 

我希望将表a中的值从表b中获取,所需的结果如下:

c1   c2      c3     c4    Value
a   david    cd      N    5
b   david    ab      Y    6   
c   all      cd      N    7

这是使用默认"全部"如果没有匹配匹配查找值。

非常感谢!

1 个答案:

答案 0 :(得分:0)

我假设你的示例结果数据中有一些错误,我认为有几种可能性。 (值为5的C2和值6的C3对我来说是可疑的)

  1. 使用CTE将结果全部替换为null并使用聚合来获取最大值
  2. 如果不是all使用它,则使用Join on值并评估表a的每个c列的值,否则使用B的值。 (如果a和b都是我们使用的并不重要。)如果两个值都有可能不同,如果值6在A中有Y,在B中有N,则这可能会有问题。但是没有这样的例子出现在你的数据,所以我相信它不会发生。 (如果确实如此,如果不是全部,选择A的值更合适)
  3. AS a cte :(公共表格表达式)

    WITH cte as (
    SELECT replace(c1,'all',null)
         , replace(c2,'all',null)
         , replace(c3,'all',null)
         , replace(c4,'all',null)
         , value
    FROM A
    UNION ALL
    SELECT replace(c1,'all',null)
         , replace(c2,'all',null)
         , replace(c3,'all',null)
         , replace(c4,'all',null)
         , value
    FROM b)  
    /* We have to eval the max as if it's null we need to replace it with all
       Might be able to avoid the replacing all provided all values of c1-c4 are   
       greater than all...  replacing just seemed safer. at a hit to performance.*/
    SELECT coalesce(max(c1),'all') as c1
          ,coalesce(max(c2),'all') as c2
          ,coalesce(max(c3),'all') as c3
          ,coalesce(max(c4),'all') as c4
          ,value
    FROM cte
    GROUP BY value
    

    使用连接(从维护和性能角度来看更简单)

    SELECT case when A.C1 <> 'all' then A.C1 else B.c1 end as C1,
           case when A.C2 <> 'all' then A.C2 else B.c2 end as C2,
           case when A.C3 <> 'all' then A.C3 else B.c3 end as C3,
           case when A.C4 <> 'all' then A.C4 else B.C4 end as C4,
           A.value --A.val = b.val so it doesn't matter which se use.
    FROM A
    INNER JOIN B
     on A.value = B.Value
    

    根据现有索引和数据量,第一种方法可能优于第二种方法。