完全连接并连接具有多个键的两个表

时间:2011-10-31 08:20:08

标签: sql oracle join key

我需要使用多个键完全连接两个表

作为一个例子,我有两个表,一个看起来像:

id1 | foreignerkey | name | value
 1         5         name1    1
 2         6         name2    2
 3         7         name4    3

t01;另一个看起来像:

id2 | foreignerkey | name | value
 1         5         name1  1
 2         7         name2  2
 3         8         name2  3

t02

我需要“select t01.* , to2.* from t01 full join t02 on t01.name = t02.name”, 但我还需要“select t01.* , t02.* from t01 join t02 where t01.foreignerkey = t02.foreignerkey”,我需要的结果是这样的:

 id1 | foreignerkey | name | value | id2 | foreignerkey | name | value
  1         5         name1    1      1         5         name1    1
  2         6         name2    2     null     null        null    null
  3         7         name4    3     null     null        null    null
 null     null        null    null    2         7         name2    2
 null     null        null    null    3         8         name2    3

问题是,正如你所看到的,首先,我把我的查询字符串这样, “select t01.* , t02.* from t01 full join t02 on t01.name = t02.name where t01.foreignerkey = t02.foreignerkey”,但是当t01.name = "name4"(不在t02中)时,它将不会显示在结果中。

所以,我的最终查询字符串:

select a.* from
    (select t01.id1, t01.foreignerkey as foreignerkey1, t01.name, t01.value,
            t02.id2, t02.foreignerkey as foreignerkey2, t02.name, t02.value 
    from t01 
    full join t02 
    on t01.name = t02.name) a
where a.foreignerkey1 = a.foreignerkey2 
      or a.foreignerkey1 is null 
      or a.foreignerkey2 is null

获得结果需要花费太多,是否有更好的解决方案?

4 个答案:

答案 0 :(得分:1)

我不明白为什么你需要内部查询

select t01.id1,t01.foreignerkey as foreignerkey1,t01.name,t01.value,
    t02.id2,t02.foreignerkey as foreignerkey2,t02.name,t02.value 
from t01 
full outer join t02 on a.foreignerkey1=a.foreignerkey2 AND t01.name = t02.name

答案 1 :(得分:1)

我无法验证这是否更快,因为您的原始SQL无法在我正在使用的Oracle版本上运行,但您可以尝试这样做:

SELECT *
  FROM t01, t02
 WHERE t01.NAME = t02.NAME
   AND t01.foreignerkey = t02.foreignerkey
UNION ALL
SELECT t01.*, NULL, NULL, '', ''
  FROM t01
 WHERE NOT EXISTS (SELECT NULL
          FROM t02
         WHERE t01.NAME = t02.NAME
           AND t01.foreignerkey = t02.foreignerkey)
UNION ALL
SELECT NULL, NULL, '', '', t02.*
  FROM t02
 WHERE NOT EXISTS (SELECT NULL
          FROM t01
         WHERE t01.NAME = t02.NAME
           AND t01.foreignerkey = t02.foreignerkey)
  • 使用内连接到t01.NAME = t02.NAME AND t01.foreignerkey = t02.foreignerkey
  • 使用NOT EXISTS从t01获取t01中没有匹配项的记录
  • 使用NOT EXISTS从t02获取t01中没有匹配项的记录
  • 在这种情况下使用UNION加入结果集ALL是安全的,因为我们知道这三个结果集是互斥的

或者你可以使用外部联接作为@kedar kamthe sugested:

SELECT *
  FROM t01, t02
 WHERE t01.NAME = t02.NAME(+)
   AND t01.foreignerkey = t02.foreignerkey(+)
UNION
SELECT NULL, NULL, '', '', t02.*
  FROM t02
 WHERE NOT EXISTS (SELECT NULL FROM t01 WHERE t01.NAME = t02.NAME  AND  t01.foreignerkey = t02.foreignerkey)

但是你仍然需要第二个查询来从t02返回结果

答案 2 :(得分:0)

您可以在 foreignerkey 名称列中使用“外部加入”。

答案 3 :(得分:0)

我创建了多个键的连接字段并使用了完全外连接,如下所示的sql。 我不知道它适合你的情况,但它解决了我的情况

select * from 
(select *, foreignerkey || name as mk from t01) tt1
full outer join
(select *, foreignerkey || name as mk from t02) tt2 on tt1.mk = tt2.mk