限制LEFT JOIN

时间:2009-04-16 20:40:05

标签: sql oracle

我有一个表,我们称之为“a”,它在一个涉及大量表的视图中的左连接中使用。但是,如果它们也与另一个表“b”连接,我只想返回“a”行。所以现有代码看起来像

SELECT ....
FROM main ...
...
LEFT JOIN a ON (main.col2 = a.col2)

但它返回太多行,特别是b中没有匹配的行。我试过了

SELECT ...
FROM main ...
...
LEFT JOIN (
   SELECT a.col1, a.col2
   FROM a
   JOIN b ON (a.col3 = b.col3)) ON (a.col2 = main.col2)

这给了我正确的结果但不幸的是“EXPLAIN PLAN”告诉我这样做会最终强制a和b的全表扫描,这使得事情变得非常缓慢。我的一个同事在b上建议了另一个LEFT JOIN,但这不起作用,因为它在它出现时给了我b行,但是没有停止从b中没有匹配的行返回行。

有没有办法将main.col2条件放在子SELECT中,这样可以摆脱全表扫描?或者其他一些方法来做我想要的事情?

5 个答案:

答案 0 :(得分:6)

SELECT ...
FROM ....
LEFT JOIN ( a INNER JOIN b ON .... ) ON ....

答案 1 :(得分:3)

  1. 添加一个where(main.col2 = a.col2)

  2. 只是进行连接而不是左连接。

答案 2 :(得分:0)

如果你创建了一个让你获得“a”到“b”连接的视图,然后你的左连接到那个视图怎么办?

答案 3 :(得分:0)

    Select ... 
    From Main 
     Left Join a on main.col2 = a.col2
    where a.col3 in (select b.col3 from b) or a.col3 is null

您可能还需要对a.col3和b.col3进行一些索引

答案 4 :(得分:0)

首先在表“a”和“b”之间定义查询,以确保它返回您想要的行:

Select
   a.field1,
   a.field2,
   b.field3
from
   table_a a

   JOIN table_b b
      on (b.someid = a.someid)

然后将其作为主查询的子查询:

select
   m.field1,
   m.field2,
   m.field3,
   a.field1 as a_field1,
   b.field1 as b_field1
from
   Table_main m

   LEFT OUTER JOIN
      (
      Select
         a.field1,
         a.field2,
         b.field3
      from
         table_a a

         JOIN table_b b
            on (b.someid = a.someid)
      ) sq
   on (sq.field1 = m.field1)

应该这样做。

啊,错过了性能问题说明 - 我通常最终要做的是将查询从存储过程中的视图中调出来,这样我就可以生成对临时表的子查询并在其上放置索引。比你想象的要快得多。 : - )