MySQL SELECT x ОТ ГДЕ НЕ ВХОДИТ (SELECT x ОТ b) - Неожиданный результат - PullRequest
29 голосов
/ 16 июня 2009

Я ожидаю, что результат третьего запроса ниже будет содержать id = 732. Это не так. Почему это так?

mysql> SELECT id FROM match ORDER BY id DESC LIMIT 5 ;
+------------+
|         id |
+------------+
|        732 | 
|        730 | 
|        655 | 
|        458 | 
|        456 | 
+------------+
5 rows in set (0.00 sec)

mysql> SELECT id FROM email ORDER BY id DESC LIMIT 5 ;
+------------+
|         id |
+------------+
|        731 | 
|        727 | 
|        725 | 
|        724 | 
|        723 | 
+------------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM match WHERE id NOT IN ( SELECT id FROM email ) ;
Empty set (0.00 sec)

В таблице email.id есть три записи NULL, а в match.id нет записей NULL.

Полная таблица / запросы можно увидеть на http://pastebin.ca/1462094

Ответы [ 4 ]

44 голосов
/ 16 июня 2009

Из документации :

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

Это именно ваш случай.

И IN, и NOT IN возвращают NULL, что не является приемлемым условием для WHERE предложения.

Перепишите ваш запрос следующим образом:

SELECT  *
FROM    match m
WHERE   NOT EXISTS
        (
        SELECT  1
        FROM    email e
        WHERE   e.id = m.id
        )
38 голосов
/ 14 сентября 2010

... или если вы действительно хотите использовать NOT IN, вы можете использовать

SELECT * FROM match WHERE id NOT IN ( SELECT id FROM email WHERE id IS NOT NULL)
6 голосов
/ 16 июня 2009

Я немного не в курсе деталей того, как MySQL работает с нулями, но вот две вещи, которые нужно попробовать:

SELECT * FROM match WHERE id NOT IN 
    ( SELECT id FROM email WHERE id IS NOT NULL) ;

SELECT
    m.*
FROM
    match m
    LEFT OUTER JOIN email e ON
        m.id = e.id
        AND e.id IS NOT NULL
WHERE
    e.id IS NULL

Второй запрос выглядит нелогичным, но он выполняет условие соединения, а затем условие where. Это тот случай, когда объединения и предложения не эквивалентны.

0 голосов
/ 17 мая 2012

Вот некоторый SQL, который действительно имеет смысл:

SELECT m.id FROM match m LEFT JOIN email e ON e.id = m.id WHERE e.id IS NULL

Просто всегда лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...