Невозможно выполнить фильтрацию по принципу «где не в» - PullRequest
1 голос
/ 03 апреля 2019

У меня есть база данных SQLite с двумя таблицами, каждая со строкой id.Я пытаюсь отфильтровать данные из таблицы1 на основе того, что не в таблице2.Таблица1 имеет, например:

In: SELECT id FROM table1 LIMIT 4
Out: 
'0000001'
'0000002
'0000003'
'0000004'

И таблица2 имеет:

In: SELECT id FROM table2 LIMIT 10
Out: 
None
None
None
'0001098'
'0001098'
'0001098'
'0001098'
'0001098'
'0001098'
'0001098'

Я хотел бы вернуть все значения из таблицы1, чей столбец идентификатора отсутствует в таблице2, который я пытаюсьделать с:

SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2)

Но это не возвращает значений.Если я использую SELECT id FROM table1 EXCEPT SELECT id FROM table2, он работает нормально.Как я понимаю, WHERE COLUMN NOT IN - это стандартный метод для выполнения того, что я пытаюсь сделать.Что я делаю не так?

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Причина в том, что id в table2 содержит null значения.Если вы используете это:

SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2 WHERE id IS NOT null)

, это будет работать.Я не нашел ничего в документации SQLite об этом случае, но для MySQL от: https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#function_in

Чтобы соответствовать стандарту SQL, INвозвращает NULL не только если выражение в левой части равно NULL, но также если совпадение не найдено в списке и одно из выражений в списке равно NULL

Итак это стандарт SQL , и это означает, что в вашем случае выражение:

IN (SELECT id FROM table2)

возвращает NULL, а затем

NOT IN (SELECT id FROM table2)

также возвращает NULL.Таким образом, ваше состояние не оценивается как TRUE, и вы не получите никаких результатов.

0 голосов
/ 03 апреля 2019

Вместо этого используйте NOT EXISTS

SELECT id 
FROM table1 t1
WHERE NOT EXISTS(SELECT 1 FROM table2 t2 WHERE t1.id = t2.id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...