Ограничение левого соединения - PullRequest
5 голосов
/ 17 апреля 2009

У меня есть таблица, давайте назовем ее «a», которая используется в левом соединении в представлении, которое включает в себя множество таблиц. Однако я хочу вернуть только строки «a», если они также соединяются с другой таблицей «b». Таким образом, существующий код выглядит как

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

но он возвращает слишком много строк, особенно те, где a не соответствует в 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, что делает процесс довольно медленным. Один из моих коллег предложил еще один LEFT JOIN на b, но это не сработает, потому что он дает мне строку b, когда она присутствует, но не прекращает возвращать строки из a, у которых нет совпадения в b.

Есть ли способ поместить условие main.col2 в sub-SELECT, что избавило бы от полного сканирования таблицы? Или каким-то другим способом делать то, что я хочу?

Ответы [ 5 ]

6 голосов
/ 17 апреля 2009
SELECT ...
FROM ....
LEFT JOIN ( a INNER JOIN b ON .... ) ON ....
3 голосов
/ 17 апреля 2009
  1. добавить где (main.col2 = a.col2)

  2. просто сделайте соединение вместо левого соединения.

0 голосов
/ 17 апреля 2009

Сначала определите ваш запрос между таблицами "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)

это должно сделать.

Ааа, пропустил заметку о проблеме с производительностью - я обычно заканчиваю тем, что помещаю запрос из представления в хранимую процедуру, чтобы я мог сгенерировать подзапросы к временным таблицам и поместить в них индексы. Удивительно быстрее, чем вы ожидаете. : -)

0 голосов
/ 17 апреля 2009
    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

0 голосов
/ 17 апреля 2009

Что, если вы создали представление, которое соединяет вас от "a" до "b", тогда ваши объединения слева направляются на это представление?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...