Какой лучший способ использовать LEFT OUTER JOIN для проверки на отсутствие связанных строк - PullRequest
9 голосов
/ 04 мая 2011

Используя MySQL 5.x, я хочу эффективно выбрать все строки из таблицы X, где нет связанной строки в таблице Y, удовлетворяющей некоторому условию, например

Дайте мне все записи в X, где связанный Y с foo = bar НЕ существует

SELECT count(id) FROM X
LEFT OUTER JOIN Y ON y.X_id = X.id AND y.foo = 'bar'
WHERE y....?

Насколько я понимаю, левое внешнее объединение гарантированно создаст строку для каждой строки в левой (первой) таблице - в данном случае X - независимо от того, была ли найдена удовлетворительная строка в объединенной таблице. Затем я хочу выбрать только те строки, в которых не было найдено ни одной строки.

Мне кажется, что y.X_id должен быть NULL, если нет подходящей записи, но этот тест, похоже, не работает. Также y.X_id = 0 или! Y.X_id.

Редактирует : исправлена ​​ошибка транскрипции (ON не AS), на которую указывали несколько ответов. Исправлена ​​грамматическая ошибка.

Ответы [ 5 ]

19 голосов
/ 04 мая 2011
SELECT count(id) FROM X 
LEFT OUTER JOIN Y ON (y.X_id = X.id AND y.foo = 'bar')
WHERE y.X_id is null

Вы были близки.

Сначала выполните объединение как обычно, затем выберите все строки, для которых строка not null в Y на самом деле равна null, так что вы уверены, что в Y отсутствует значение "no match", а не просто значение null. .

Также обратите внимание на опечатку (с момента исправления), которую вы сделали в запросе:

LEFT OUTER JOIN Y AS
-- should be
LEFT OUTER JOIN Y ON
-- This however is allowed
LEFT OUTER JOIN table2 as Y ON ....
4 голосов
/ 04 мая 2011

Проверка того, что первичный ключ таблицы Y равен NULL, поможет, что соединение не соответствует:

SELECT count(id) FROM X 
LEFT OUTER JOIN Y ON (y.X_id = X.id AND y.foo = 'bar')
WHERE y.Y_id is null
2 голосов
/ 04 мая 2011

Йохан правильный ответ 100%.

Кроме того, есть также эта опция:

SELECT count(id)
FROM X 
WHERE NOT EXISTS
  ( SELECT * 
    FROM Y
    WHERE (y.X_id = X.id AND y.foo = 'bar')
  )

В зависимости от размера таблицы и распределения данных это может быть более эффективным. Проверьте и сохраните оба пути для дальнейшего использования.

0 голосов
/ 21 марта 2017

Вы должны помнить, что NULL - это особое значение! И вот почему я в MySQL. У вас есть глава под названием "4.3.4.6 Работа со значениями NULL" .

ссылка: https://dev.mysql.com/doc/refman/5.7/en/working-with-null.html

наслаждаться!

0 голосов
/ 04 мая 2011

Зачем использовать внешнее соединение? Не могли бы вы просто сделать:

SELECT count(id) 
FROM X JOIN Y AS y.X_id = X.id AND y.foo <> 'bar'
...