Select B.num
From BonInterne As B
Left Join LigneBonInterne As L
On L.numBon = B.num
Where L.numBon Is Null
SQL Fiddle version
Visual Explanation of Joins
Одно из объяснений, почему ваш исходный запрос не работают, если LigneBonInterne
таблица содержит нулевые значения для numBon
столбца. Функция In
преобразуется в ряд операторов Or
(например, Foo In(A,B,C)
соответствует Foo = A Or Foo = B Or Foo = C
. В случае Foo Not In(A,B,C)
мы получаем Foo <> A And Foo <> B And Foo <> C
.). Таким образом, если одно из значений равно null, мы получим сравнение с нулем и вернем false (технически оно возвращает Unknown).
Этот SQL Fiddle example показывает ваш первоначальный запрос, но обратите внимание, что я добавил значение null для numBon
и не получаю результатов. Возьмите это значение, и мы это сделаем.
Если у вас есть нули в LigneBonInterne
, то вышеуказанное решение будет работать. Другой вариант заключается в использовании функции In
но отфильтровать аннулирует в вашем подзапрос
Select B.num
From BonInterne As B
Where Not In (
Select L1.numBon
From LigneBonInterne As L1
Where L1.numBon Is Not Null
)
Другой вариант заключается в использовании Exists
вместо In
:
Select B.num
From BonInterne As B
Where Not Exists (
Select 1
From LigneBonInterne As L1
Where L1.numBon = B.num
)
При использовании Exists
, положение Select
полностью игнорируется. Некоторые люди используют Select *
, некоторые используют Select Null
, некоторые используют Select 1
. Это не имеет значения; все, что имеет значение, заключается в том, возвращает ли остальная часть запросов строки или нет. Этот тип запроса называется коррелированным подзапросом, потому что во внутреннем запросе есть ссылка на внешний запрос (L1.numBon = B.num
).
Итак, в какой форме вы должны использовать? В этом случае ясность намерения может быть достигнута любой из трех форм. Однако продукты базы данных отличаются своей способностью эффективно обрабатывать коррелированные подзапросы. В случае с MySQL он, вероятно, будет работать лучше всего с помощью Left Join, затем функции In и последней функции Exists.
Я просто проверял свой запрос, и он работает - http://www.sqlfiddle.com/#!2/c8bdf0/1 – Taryn
@bluefeet в моей реальной базе данных есть значения NULL в столбце 'numBon'. Я думал, что не важно включать значения NULL в мой пример, см. изменения, которые я сделал. –
Это меняет вещи, это детали, которые очень важны для ответа. – Taryn