Каскад внешних объединений - PullRequest
4 голосов
/ 21 февраля 2011

В качестве схематического примера у меня есть 3 таблицы, к которым я хочу присоединиться, A, B, C, где A-B соединяется посредством внешнего соединения, а B-C потенциально соединяется посредством внутреннего соединения. В этом созвездии мне нужно написать два внешних объединения, чтобы получить данные, если первое соединение не имеет совпадения A-B в строке:

SELECT [fields] FROM
       A
       LEFT OUTER JOIN
       B ON [a.field]=[b.field] 
       LEFT OUTER JOIN
       C ON [b.field]=[c.field]

Мне кажется, логично, что я должен написать второе утверждение как внешнее соединение. Однако мне любопытно, есть ли возможность установить скобки для области соединения, чтобы указать, что второе соединение должно использоваться только в том случае, если первое внутреннее соединение обнаружило совпадающие данные для A-B. Что-то вроде:

SELECT [fields] FROM
       A
      (LEFT OUTER JOIN
       B ON [a.field]=[b.field] 
       INNER JOIN
       C ON [b.field]=[c.field]
       )

Я немного поиграл, но не нашел возможности установить брекеты. Единственный способ, который я нашел, чтобы заставить это работать - это подзапрос. Это единственный путь?

Ответы [ 4 ]

4 голосов
/ 21 февраля 2011

На самом деле есть синтаксис для этого случая.

SELECT fields
FROM A
  LEFT OUTER JOIN (
    B INNER JOIN C ON b.field = c.field
  ) ON a.field = b.field

Скобки необязательны, и результат без них одинаков, эквивалентен результату

SELECT fields
FROM A
  LEFT OUTER JOIN B ON a.field = b.field
  LEFT OUTER JOIN C ON b.field = c.field
2 голосов
/ 21 февраля 2011

Вы могли бы выполнить это следующим образом

SELECT Fields 
FROM TableA a
LEFT OUTER JOIN (SELECT Fields
                 FROM TableB b
                 INNER JOIN TableC c ON b.Field = c.Field) x on a.Field = x.Fi

eld

Не слишком уверен, что будет какое-то преимущество в производительности без тестирования, хотя.

1 голос
/ 21 февраля 2011

2-ой путь будет с подзапросом согласно ответу Джона Бриджеса

Однако, они семантически одинаковы.

A CTE можно использовать, если выесть сложный подзапрос

;WITH BjoinC AS
(
    SELECT Fields
    FROM TableB b
    INNER JOIN
    TableC c ON b.Field = c.Field
)
SELECT [fields] FROM
       A
       LEFT OUTER JOIN
       BjoinC ON ...
0 голосов
/ 21 февраля 2011

Как насчет чего-то вроде:

SELECT [fields] 
FROM A 
LEFT JOIN ( SELECT DISTINCT [fields]
            FROM B
            LEFT JOIN C ON b.field = c.field
          ) on a.field = b.field
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...