Я пытаюсь выполнить этот запрос:
SELECT mac, creation_date
FROM logs
WHERE logs_type_id=11
AND mac NOT IN (select consols.mac from consols)
Но я не получаю результатов. Я проверил его и знаю, что с синтаксисом что-то не так. В MySQL такой запрос отлично работает. Я добавил строку, чтобы убедиться, что mac
в consols
таблице есть строка, которой нет , но она все равно не дает никаких результатов.
postgresql
subquery
сковрон-линия
источник
источник
consols.mac
столбецNULL
илиNOT NULL
?Ответы:
При использовании NOT IN вы должны убедиться, что ни одно из значений не является NULL:
SELECT mac, creation_date FROM logs WHERE logs_type_id=11 AND mac NOT IN ( SELECT mac FROM consols WHERE mac IS NOT NULL -- add this )
источник
WHERE mac IS NOT NULL
предложение в подзапросе не требуется, посколькуIn(...)
всегда удаляет NULL (и дублирует). Потому что набор не может содержать NULLIS NOT NULL
. ВложенныйSELECT
возвращал несколькоNULLS
, и это сбивало с толкуIN(SELECT...)
.IS NOT NULL
это работает.NULL
вNOT IN
предложении не работает, потому что сравнение с неNULL
является ни истинным, ни ложным. sqlbadpractices.com/using-not-in-operator-with-null-valuesis not null
если подзапрос не дает совпадающих значений и хотя бы одноnull
значение. Из раздела 9.22 текущего (версия 10) руководства PostgreSQL: «[…] если нет равных правых значений и хотя бы одна правая строка дает ноль, результатом конструкции NOT IN будет NULL, а не истина . "При использовании NOT IN вы также должны учитывать NOT EXISTS, который молча обрабатывает нулевые случаи. См. Также PostgreSQL Wiki
SELECT mac, creation_date FROM logs lo WHERE logs_type_id=11 AND NOT EXISTS ( SELECT * FROM consols nx WHERE nx.mac = lo.mac );
источник
NOT EXISTS
vs... NOT IN
Вы также можете использовать условие LEFT JOIN и IS NULL:
SELECT mac, creation_date FROM logs LEFT JOIN consols ON logs.mac = consols.mac WHERE logs_type_id=11 AND consols.mac IS NULL;
Индекс столбцов «mac» может повысить производительность.
источник