MySQL: вибір рядків, де стовпець є нульовим


270

У мене виникає проблема, коли я намагаюся вибрати рядки, у яких є NULL для певного стовпця, він повертає порожній набір. Однак, коли я переглядаю таблицю в phpMyAdmin, вона говорить про нуль для більшості рядків.

Мій запит виглядає приблизно так:

SELECT pid FROM planets WHERE userid = NULL

Порожній набір щоразу.

Дуже багато місць сказано, щоб переконатися, що вони не зберігаються як "NULL" або "null" замість фактичного значення, і можна сказати, щоб спробувати шукати просто пробіл ( userid = ' '), але жодне з них не спрацювало. Була запропонована можливість не використовувати MyISAM та користуватися innoDB, оскільки MyISAM має проблеми зі збереженням нуля. Я переключив таблицю на innoDB, але тепер я відчуваю, що проблема може полягати в тому, що вона все ще насправді не є нульовою через спосіб її перетворення. Я хотів би це зробити, не відтворюючи таблицю якDinDB або щось інше, але якщо доведеться, я, безумовно, можу спробувати це.


1
У MyISAM немає проблем із збереженням нуля. Сама семантика NULL повинна бути незалежною від двигуна.
MarkR

Відповіді:


512

SQL NULL особливий, і ви повинні це зробити WHERE field IS NULL, оскільки NULL не може бути рівним нічому,

включаючи себе (тобто: NULL = NULL завжди хибно).

Дивіться Rule 3 https://en.wikipedia.org/wiki/Codd%27s_12_rules


24
Це невідомо - Неправда. SQL використовує три значення логіки.
Мартін Сміт

38
NULL = NULL насправді НЕ БУЛЬШИЙ - знову це NULL. Але це не ІСТИНА, тому IF (NULL = NULL) не буде виконано.
Конерак

1
див. також відповідь @obe: SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1, 1, 0
Томас

Мало того, що null не є рівним ні до чого, він не є рівним нічому. Іншими словами, select * from foo where bar <> "abc"буде НЕ повертати рядки , де бар є нульовим. Це сьогодні кинуло мене на цикл. Документи називають <>оператором "не рівний", але насправді це "дорівнює чомусь іншому, ніж" оператору.
StackOverthrow


39

Оскільки всі дані відповіді, я хочу додати трохи більше. Я також стикався з тим же питанням.

Чому ваш запит не вдався? Ти маєш,

SELECT pid FROM planets WHERE userid = NULL;

Це не дасть вам очікуваного результату, оскільки від mysql doc

У SQL значення NULL ніколи не відповідає дійсності порівняно з будь-яким іншим значенням, навіть NULL. Вираз, який містить NULL, завжди створює значення NULL, якщо інше не вказано в документації для операторів та функцій, що беруть участь у виразі.

Наголос мій.

Для пошуку значень стовпців NULL, ви не можете використовувати expr = NULLтест. Наступне твердження не повертає жодних рядків, тому що expr = NULLніколи не відповідає дійсності для будь-якого виразу

Рішення

SELECT pid FROM planets WHERE userid IS NULL; 

Для тестування NULLвикористовуйте оператори IS NULLта IS NOT NULL.



11

Інформація з http://w3schools.com/sql/sql_null_values.asp :

1) Значення NULL являють собою відсутні невідомі дані.

2) За замовчуванням стовпчик таблиці може містити значення NULL.

3) Значення NULL трактуються інакше, ніж інші значення

4) Неможливо порівняти NULL та 0; вони не рівнозначні.

5) Неможливо перевірити значення NULL з операторами порівняння, такими як =, <або <>.

6) Нам доведеться використовувати оператори IS NULL, а НЕ 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

У мене була така ж проблема при перетворенні баз даних з доступу до 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.