SQL Server: как сделать запрос с левым внешним соединением + зависимым внутренним соединением? - PullRequest
1 голос
/ 06 декабря 2010

У меня проблема с объединением в базе данных sql server 2005. У меня есть следующая структура таблиц:

 TableA --LEFT JOIN--> TableB --INNER JOIN-->TableC

Итак, если я напишу запрос, подобный этому:

SELECT TableA.* FROM TableA
LEFT OUTER JOIN TableB ON TableA.keyOfB = TableB.key
INNER JOIN TableC ON TableB.keyOfC = TableC.key
where TableA.key = aValue

он читает 0 записей, если нет записи TableB, связанной с TableA записью. Но TableB находится во внешнем соединении, поэтому я не ожидал этого. Другими словами, ВНУТРЕННЕЕ СОЕДИНЕНИЕ не должно было учитываться, потому что нет никакой записи TableB! Что мне не хватает?

Ответы [ 5 ]

1 голос
/ 06 декабря 2010

Я думаю, что это связано с порядком операций JOIN.

В результате (ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ B) ВНУТРЕННЕГО СОЕДИНЕНИЯ C, вы хотите ВНЕШНИЙ ВНЕШНИЙ (ВНУТРЕННЕЕ СОЕДИНЕНИЕ B).

Попробуйте добавить туда ().

Или попробуйте изменить порядок своих СОЕДИНЕНИЙ, чтобы ... B ВНУТРЕННЯЯ C ПРАВАЯ НАРУЖНАЯ A, чтобы получить (B ВНУТРЕННЯЯ C) ПРАВАЯ НАРУЖНАЯ A.

EDIT: Пример того, о чем я думал:

SELECT TableA.* FROM TableA
LEFT OUTER JOIN (TableB INNER JOIN TableC ON TableB.keyOfC = TableC.key) 
ON TableA.keyOfB = TableB.key
WHERE TableA.key = aValue

Переключение на ПРАВО НАРУЖНО:

SELECT TableA.* FROM TableB 
INNER JOIN TableC ON TableB.keyOfC = TableC.key
RIGHT OUTER JOIN TableA ON TableA.keyOfB = TableB.key
WHERE TableA.key = aValue

ПРИМЕЧАНИЕ. Простите, если это не работает, я не трогал SqlServer с версии 7.

1 голос
/ 06 декабря 2010

Это ведет себя именно так, как и должно. Ваша ссылка с TableC проходит через TableB, поэтому ссылка не будет подключена, если нет записи в TableB.

Также можно изменить INNER JOIN на LEFT OUTER - хотя это действительно внутренняя часть данных.

1 голос
/ 06 декабря 2010

Если вы выполните запрос без INNER JOIN, будут все записи с TableB.key null, верно?Поэтому следующий INNER JOIN не может найти ни одной подходящей записи, поэтому результата нет.

1 голос
/ 06 декабря 2010

Использовать виртуальную таблицу для соединения (B + C).
РЕДАКТИРОВАТЬ: Что-то вроде:

SELECT TableA.* FROM TableA
LEFT OUTER JOIN 
   (select key from TableB INNER JOIN TableC ON TableB.keyOfC = TableC.key) as TableBC 
   ON TableA.keyOfB = TableBC.key
where TableA.key = aValue
0 голосов
/ 06 декабря 2010

Здесь приведен пример использования оставленного соединения как для таблиц b, так и для c.

declare @TableA table (Adata1 char(2), Adata2 char(2))
declare @TableB table (Bdata1 char(2), Bdata2 char(2))
declare @TableC table (Cdata1 char(2), Cdata2 char(2))

;Insert @TableA 
Select 'A', 'A' union all
Select 'B', 'B' union all
Select 'C', 'C'

;Insert @TableB 
Select 'Ab', 'Ab' union all
Select 'B', 'B' union all
Select 'C', 'C'

;Insert @TableC 
Select 'A', 'A' union all
Select 'B', 'B' union all
Select 'Cb', 'Cb'

--Select * From @TableA
--Select * From @TableB
--Select * From @TableC

Select * from @TableA
LEFT OUTER JOIN @TableB on Adata1 = Bdata1
LEFT OUTER JOIN @TableC on Bdata1 = Cdata1

Результаты:

Adata1  Adata2  Bdata1  Bdata2  Cdata1  Cdata2
A            A  NULL    NULL    NULL    NULL
B            B  B   B   B   B 
C            C  C   Cb  NULL    NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...