Возвращать строки, даже если запись не существует LEFT OUTER JOIN - PullRequest
25 голосов
/ 06 мая 2011

У меня есть 2 таблицы ниже:

Table_1
[Group No] [Test No] [Description]
123        1         [First Test]
123        2         [Second Test]
123        3         [Third Test]

Table_2
[Sample No] [Test No] [Result Description]
ABC         1         [Some More Result]
ABC         3         [Some Result]
DEF         1         [A Result]
DEF         2         [Results More]
DEF         3         [Bad Results]

Вот мой запрос:

SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
FROM Table_1 
LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No]
WHERE (Table_1.[Group No] = '123') AND (Table_2.[Sample No] = 'ABC')

запрос Дьякобсона:

SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
FROM Table_1 
LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No]
WHERE (Table_1.[Group No] = '123') 
  AND (Table_2.[Sample No] IS NULL OR Table_2.[Sample No] = 'ABC')

Возвращает:

[Group No] [Test No] [Description] [Result Description]
123        1         [First Test]  [Some More Result]
123        3         [Third Test]  [Some Result]

Но то, что я действительно хочу, это:

[Group No] [Test No] [Description] [Result Description]
123        1         [First Test]  [Some More Result]
123        2         [Second Test] NULL
123        3         [Third Test]  [Some Result]

Возможно ли это? Я хотел бы вернуть запись с тестом № 2. Однако, как мне присоединиться к записи, которой нет? Или это просто невозможно? Какие есть альтернативы?

1 Ответ

43 голосов
/ 06 мая 2011

Несмотря на правильное использование внешнего соединения, вы ограничиваете набор результатов случаями, когда значение присутствует в Table_2, включая столбец из этой таблицы в предложение WHERE.Если вам нужны записи, где № образца - ABC, ИЛИ в Таблице_2 нет записи, вам нужно сделать это:

SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
FROM Table_1 
LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No]
WHERE (Table_1.[Group No] = '123') 
  AND (Table_2.[Sample No] IS NULL OR Table_2.[Sample No] = 'ABC')

В качестве альтернативы, вы можете отфильтровать результаты из Таблицы_2 при присоединении к ней (чтов этом случае читается немного более чисто):

SELECT Table_1.[Group No], Table_1.[Test No], Table_1.Description, Table_2.[Result Description]
FROM Table_1 
LEFT OUTER JOIN Table_2 ON Table_1.[Test No] = Table_2.[Test No] AND Table_2.[Sample No] = 'ABC'
WHERE (Table_1.[Group No] = '123') 

Это должно сделать то же самое.Здесь важно отметить, что предложение WHERE фильтрует результаты объединения ваших таблиц.Если вы используете внешние объединения, но хотите отфильтровать таблицы с внешними соединениями, вы должны обработать случай, когда на дальней стороне соединения нет записи.

...