oracle - 三个select语句的sql full outer join

时间:2011-11-04 19:41:07

标签: sql oracle full-outer-join

我想从三个表中选择值。每个表都有一个buyer_entity_id列。

我已经提出了在两个表上进行外连接的语法,但是如何添加第三个表是我的意思。

这是两个表连接的语句,它完全按照我希望的方式工作:

select * from (select  b.buyer_entity_id, count(distinct(a.row_id)) as imps 
from imps a, anl_line b
where b.line_item_id=a.buyer_line_id 
and a.entity_id=3
group by b.buyer_entity_id
order by b.buyer_entity_id) tab1
full outer join (select b.buyer_entity_id, count(distinct(a.row_id)) as clicks 
from clicks a, anl_line b 
where a.buyer_line_id=b.line_item_id 
and a.entity_id=3
group by b.buyer_entity_id 
order by b.buyer_entity_id) tab2
on tab1.buyer_entity_id = tab2.buyer_entity_id;

第三个表将具有相同的select语句,并且还将在buyer_entity_id值上加入。但是,当我添加第三个select语句时,我收到一个“缺少关键字”错误。下面是我的三路全外连接语句:

select * from ((select  b.buyer_entity_id, count(distinct(a.row_id)) as imps 
from imps_table a, line_table b
where b.line_item_id=a.buyer_line_id 
and a.entity_id=3
group by b.buyer_entity_id
order by b.buyer_entity_id) tab1
full outer join (select b.buyer_entity_id, count(distinct(a.row_id)) as clicks 
from clicks_table a, line_table b 
where a.buyer_line_id=b.line_item_id 
and a.entity_id=3
group by b.buyer_entity_id 
order by b.buyer_entity_id) tab2)
outer join (select  b.buyer_entity_id, count(distinct(a.row_id)) as vers 
from vers_table a, line_table b
where b.line_item_id=a.buyer_line_id 
and a.entity_id=3
group by b.buyer_entity_id
order by  b.buyer_entity_id) tab3
on tab1.buyer_entity_id = tab2.buyer_entity_id and tab2.buyer_entity_id=tab3.buyer_entity_id;

3 个答案:

答案 0 :(得分:1)

您可以使用WITH子句简化一下:

以first_part为 ((select ....)outer join(select ....)); select * from first_part outer join(select ....);

您可能希望重新审视整体逻辑,看看是否有更好的方法来完成您尝试做的事情。多个外连接通常不是最有效的解决方案。

答案 1 :(得分:1)

错误在于:order by b.buyer_entity_id) tab2)。您需要on子句来指定tab1和amp;之间的连接条件。 TAB2。 order by b.buyer_entity) tab1 on <join condition)

一旦修复完毕。您需要将full添加到下一行,以便outer join (select b.buyer_entity_id, count(distinct(a.row_id)) as vers变为full outer join (select b.buyer_entity_id, count(distinct(a.row_id)) as vers

这涵盖语法问题,但不包括语义问题。

连接是成对的表1在某些条件下连接到表2,然后结果成为下一个连接的左侧。如果tab1和tab3匹配,你想发生什么,但tab2不匹配?我猜想用tab1和tab3数据和tab2空值产生一行。类似的东西:

select * 
from (select  b.buyer_entity_id, count(distinct(a.row_id)) as imps 
        from imps_table a, line_table b
        where b.line_item_id=a.buyer_line_id 
        and a.entity_id=3
        group by b.buyer_entity_id) tab1
full outer join (select b.buyer_entity_id, count(distinct(a.row_id)) as clicks 
        from clicks_table a, line_table b 
        where a.buyer_line_id=b.line_item_id 
        and a.entity_id=3
        group by b.buyer_entity_id) tab2
    on tab1.buyer_entity_id = tab2.buyer_entity_id
full outer join (select  b.buyer_entity_id, count(distinct(a.row_id)) as vers 
        from vers_table a, line_table b
        where b.line_item_id=a.buyer_line_id 
        and a.entity_id=3
        group by b.buyer_entity_id) tab3
    on tab3.buyer_entity_id in (tab1.buyer_entity_id, tab2.buyer_entity_id)
order by coalesce(tab1.buyer_entity_id
    , tab2.buyer_entity_id
    , tab3.buyer_entity_id);

另外,请丢失子查询中的order by。他们没有为你做任何事,因为订单不能保证在连接中存活。

答案 2 :(得分:1)

更快的方法如下所述 https://forums.oracle.com/thread/2388229

SELECT       COALESCE (a.id, b.id, c.id)     AS common_id
,       NVL2 (a.id, 1, NULL)           AS table_a_flag
,       NVL2 (b.id, 1, NULL)           AS table_b_flag
,       NVL2 (c.id, 1, NULL)           AS table_c_flag
FROM              table_a  a
FULL OUTER JOIN  table_b  b  ON  b.id  =           a.id
FULL OUTER JOIN      table_c  c  ON  c.id  = COALESCE (a.id, b.id)
ORDER BY  common_id;