【问题标题】:join with exact match value otherwise join with default value加入完全匹配的值,否则加入默认值
【发布时间】:2016-04-24 02:24:48
【问题描述】:

我有一张桌子a

 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

如果没有找到匹配项,则使用默认的“all”值。

非常感谢!

【问题讨论】:

  • 为什么 c2 david 而不是 peter 在你的结果中值 5。另外为什么在你的结果中是 c3 ab 而不是所有的值 6 我没有看到我们可以建立的模式。

标签: oracle join match


【解决方案1】:

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

  1. 使用 CTE 合并结果,将所有结果替换为 null 并使用聚合获取最大值
  2. 如果不是all,则使用值连接并评估表a 的每个c 列的值,否则使用B 的值。 (如果 a 和 b 都是全部,我们使用哪个并不重要。)如果两个值可能不同,例如值 6 在 A 中有一个 Y,在 B 中有一个 N,这可能会出现问题。但没有这样的例子存在于你的数据,所以我相信它不会发生。 (或者如果是这样,如果不是全部,则选择 A 的值更合适)

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多