привет
Есть две связанные таблицы: parent и child. Таблица parent:
parent_id
---------
| 1|
| 2|
| 3|
---------
child:
id parent_fk
--------------
| 1| NULL|
| 2| 1|
| 3| NULL|
| 4| 3|
--------------
При этом запрос:
SELECT * FROM parent
WHERE parent_id NOT IN (SELECT parent_fk
FROM child)
возвращает 0 записей. А запрос
SELECT * FROM parent
WHERE parent_id NOT IN (SELECT parent_fk
FROM child
WHERE parent_fk IS NOT NULL)
возвращает 1 запись как и нужно (с parent_id = 2). Получается, что в первом случае из-за присутствия NULL в результате подзапроса ниодна запись из внешнего запроса не удовлетворяет условию NOT IN ..., т.е. все записи из parent должны удовлетворять условию IN:
1 IN (NULL, 1, NULL, 3) - true
2 IN (NULL, 1, NULL, 3) - тоже получается true :)
3 IN (NULL, 1, NULL, 3) - true
Вопрос во второй выделенной строке — что за поведение? Отмечу, что тот же запрос с простым IN отрабатывает нормально, т.е. возвращает две записи (parent_id = 1 и parent_id=3):
SELECT * FROM parent
WHERE parent_id IN (SELECT parent_fk
FROM child)