MySQL: выбор строк с нулевым столбцом


270

У меня проблема, когда при попытке выбрать строки, которые имеют NULL для определенного столбца, он возвращает пустой набор. Тем не менее, когда я смотрю на таблицу в phpMyAdmin, он говорит, что ноль для большинства строк.

Мой запрос выглядит примерно так:

SELECT pid FROM planets WHERE userid = NULL

Пустой набор каждый раз.

Во многих местах сказано, что он не хранится как «NULL» или «NULL» вместо фактического значения, а один говорит, что пытается найти только пробел ( userid = ' '), но ни одно из них не сработало. Было предложение не использовать MyISAM и использовать innoDB, потому что MyISAM имеет проблемы с хранением нулевого значения. Я переключил таблицу на innoDB, но теперь я чувствую, что проблема может заключаться в том, что она все еще не является фактически нулевой из-за способа, которым она может преобразовать ее. Я хотел бы сделать это без необходимости воссоздавать таблицу как innoDB или что-то еще, но если мне нужно, я, конечно, могу попробовать это.


1
MyISAM без проблем хранит ноль. Семантика самих NULL должна быть независимой от движка.
MarkR

Ответы:


513

SQL NULL особенный, и вы должны сделать WHERE field IS NULL, так как NULL не может быть равен чему-либо,

включая себя (то есть: NULL = NULL всегда ложно).

См. Rule 3 Https://en.wikipedia.org/wiki/Codd%27s_12_rules.


25
Неизвестно - не ложно. SQL использует трехзначную логику.
Мартин Смит

39
NULL = NULL на самом деле не FALSE - это снова NULL. Но это также не ИСТИНА, поэтому IF (NULL = NULL) не будет выполняться.
Конерак

1
см. также @obe answer: SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1, 1, 0
Томас

Мало того, что нуль не равен чему-либо, он не равен ни чему-либо. Другими словами, неselect * from foo where bar <> "abc" будет возвращать строки, где bar равен нулю. Это бросило меня в тупик сегодня. Документы вызывают оператор «не равно», но на самом деле это оператор «равен чему-то другому». <>
StackOverthrow


39

Поскольку всем даны ответы, я хочу добавить немного больше. Я также столкнулся с той же проблемой.

Почему ваш запрос не удался? У тебя есть,

SELECT pid FROM planets WHERE userid = NULL;

Это не даст вам ожидаемого результата, потому что из MySQL док

В SQL значение NULL никогда не является истинным по сравнению с любым другим значением, даже NULL. Выражение, содержащее NULL, всегда создает значение NULL, если иное не указано в документации для операторов и функций, участвующих в выражении.

Акцент мой.

Для поиска значений столбцов NULLвы не можете использовать expr = NULLтест. Следующий оператор не возвращает строк, потому что expr = NULLникогда не имеет значения true для любого выражения

Решение

SELECT pid FROM planets WHERE userid IS NULL; 

Для испытания на NULL, используйте IS NULLи IS NOT NULLоператор.


17

Там также <=>оператор:

SELECT pid FROM planets WHERE userid <=> NULL

Должно сработать. Приятно то, что<=> также может использоваться со значениями, отличными от NULL:

SELECT NULL <=> NULL доходность 1 .

SELECT 42 <=> 42 доходность 1 также.

Смотрите здесь: https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#operator_equal-to


11

Информация с http://w3schools.com/sql/sql_null_values.asp :

1) Значения NULL представляют пропущенные неизвестные данные.

2) По умолчанию столбец таблицы может содержать значения NULL.

3) значения NULL обрабатываются иначе, чем другие значения

4) Невозможно сравнить NULL и 0; они не эквивалентны.

5) Невозможно проверить значения NULL с помощью операторов сравнения, таких как =, <или <>.

6) Вместо этого нам придется использовать операторы IS NULL и IS NOT NULL

Так что в случае вашей проблемы:

SELECT pid FROM planets WHERE userid IS NULL

7

Была такая же проблема, где запрос:

SELECT * FROM 'column' WHERE 'column' IS NULL; 

не вернул никаких значений. Кажется, проблема с MyISAM, и тот же запрос к данным в InnoDB дал ожидаемые результаты.

Пошел с:

SELECT * FROM 'column' WHERE 'column' = ' '; 

Вернули все ожидаемые результаты.



0

У меня была такая же проблема при преобразовании баз данных из Access в MySQL (использование vb.net для связи с базой данных).

Мне нужно было оценить, было ли поле (тип поля varchar (1)) нулевым.

Это утверждение сработало для моего сценария:

SELECT * FROM [table name] WHERE [field name] = ''

1
Если это сработало для вас, значение по умолчанию для вашего varchar (1) - «», а не ноль, поэтому не имеет отношения к этому вопросу.
さ り げ な い 告白
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.