Oracle 使用精确匹配值联接,否则使用默认值联接

Oracle 使用精确匹配值联接,否则使用默认值联接,oracle,join,match,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
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
也就是说,如果没有接近匹配查找,则使用默认的“全部”值


非常感谢

假设您的示例结果数据中存在一些错误,我看到了一些可能性。(我怀疑C2代表值5,C3代表值6)

  • 使用CTE合并结果,将所有结果替换为null,并使用聚合获得最大值
  • 在值上使用联接,如果表a不是
    all
    使用它,则为每个c列计算表a的值,否则使用B的值。(如果a和b都是,那么我们使用哪一个并不重要。)如果两个值都可能不同,比如值6在a中有Y,在b中有N,那么这可能会有问题。但是在您的数据中没有这样的示例,所以我相信不会发生。(或者,如果确实如此,那么选择A的值更合适,如果它不是全部)
  • 作为cte:(公共表表达式)

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

    选择A.C1“全部”后A.C1其他B.C1结束为C1的情况,
    如果A.C2“全部”,则A.C2其他B.C2终止为C2,
    当A.C3为“全部”时,则A.C3为其他B.C3终止为C3,
    如果A.C4‘全部’,则A.C4其他B.C4结束为C4,
    A.value--A.val=b.val,因此使用哪个se并不重要。
    从
    内连接B
    A.值=B.值
    

    根据现有的索引和数据量,第一种方法可能比第二种更好

    为什么在你的结果中,c2是大卫而不是彼得。另外,为什么在你的结果中是c3 ab而不是全部为值6,我没有看到我们可以建立的模式。
    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