如何在带有两个左表的3个表上执行Oracle SQL左外连接?

时间:2014-12-12 19:21:36

标签: sql oracle

我试图找出使用唯一ID连接3个表的最佳方法,其中2个表需要与第3个表相比为'Left'表。第3个表将提供我分析所需的所有空值。

例如:

表1 = table_r,表2 = table_n,表3 = table_t

unique_r    unique_n     unique_t    match
abc                      abc          yes
cde                      null         no
            efg          efg          yes
            jkl          null         no

这是我想得到的一个示例结果,其中table_r与table_t的比较给出了匹配,而nulls和table_n与table_t相比给了我匹配和null。然后我会做一个简单的案例陈述,将结果与一个'匹配'列进行比较,我就会知道缺少什么。

我的各种各样的SQL看起来只是给了我一个左侧。

select * from table_r left join table_t
on unique_r = unique_t
left join table_n
on unique_n = unique_t;

感谢您的任何建议:)

3 个答案:

答案 0 :(得分:1)

根据您的示例查询,您希望结果包含所有三个表中的所有列。此外table_rtable_n似乎无关,但我想您不希望他们的行的交叉产品。这是一个相当奇怪的场景,但你应该能够像这样实现它:

SELECT *
FROM
  table_r
  FULL OUTER JOIN table_n
    ON 1 = 0
  LEFT JOIN table_t
    ON unique_r = unique_t OR unique_n = unique_t

或者,这可能会表现得更好:

SELECT *
FROM
  (
    SELECT *
    FROM table_r
      LEFT JOIN (
        SELECT *
        FROM table_n
        WHERE unique_n IS NULL
      )

    UNION ALL

    SELECT * FROM (
        SELECT *
        FROM table_r
        WHERE unique_r IS NULL
      )
      RIGHT JOIN table_n
  )
  LEFT JOIN table_t
    ON unique_r = unique_t OR unique_n = unique_t

假设基表中没有unique_runique_n值为NULL。因此,两个最里面的子查询选择包含其各自基表的所有列的结果集,但无行。因此,中间子查询中的LEFTRIGHT外连接应该非常快,但是它们应该按照相应的顺序生成具有正确列的结果,就像{{1}所需的那样}(这也将非常快)。显然,这是一个丑陋,泥泞的混乱。如果第一种选择足够快,甚至不要考虑它。

答案 1 :(得分:0)

如果table_r和table_n中有相同的字段,则可以使用*来执行UNION,否则,请指定要选择的字段,例如unique_n IS NOT NULL as match

select * from table_r left join table_t
on unique_r = unique_t
Union
select * from table_n left join table_t
on unique_n = unique_t

答案 2 :(得分:0)

从所有表中的集中式联合开始,然后将它们左连接到每个原始表...

select
      r.unique_r,
      n.unique_n,
      t.unique_t
      case when (
           case when r.unique_r is null then 0 else 1 end
         + case when n.unique_n is null then 0 else 1 end
         + case when t.unique_t is null then 0 else 1 end >= 2 ) then 'yes' else 'no' end as Matched
   from 
      ( select unique_r as base1 from table_r
        union select unique_n from table_n
        union select unique_t from table_t ) allBase
         left join table_r r
            on allBase.base1 = r.unique_r
         left join table_n n
            on allBase.base1 = n.unique_n
         left join table_t t
            on allBase.base1 = t.unique_t