MySQL: wybieranie wierszy, w których kolumna ma wartość NULL

270

Mam problem polegający na tym, że gdy próbuję wybrać wiersze z wartością NULL dla określonej kolumny, zwraca pusty zestaw. Jednak gdy patrzę na tabelę w phpMyAdmin, dla większości wierszy jest ona pusta.

Moje zapytanie wygląda mniej więcej tak:

SELECT pid FROM planets WHERE userid = NULL

Pusty zestaw za każdym razem.

Wiele miejsc mówi, aby upewnić się, że nie jest przechowywany jako „NULL” lub „null” zamiast rzeczywistej wartości, a jeden z nich powiedział, że należy poszukać spacji ( userid = ' '), ale żadne z nich nie zadziałało. Sugerowano, aby nie używać MyISAM i używać innoDB, ponieważ MyISAM ma problemy z przechowywaniem wartości null. Zmieniłem tabelę na innoDB, ale teraz wydaje mi się, że problem może polegać na tym, że wciąż nie jest zerowy z powodu sposobu, w jaki może go przekonwertować. Chciałbym to zrobić bez konieczności odtwarzania tabeli jako innoDB lub czegokolwiek innego, ale jeśli będę musiał, z pewnością mogę tego spróbować.

The.Anti.9
źródło
1
MyISAM bez problemu zapisuje wartość null. Semantyka samych wartości NULL powinna być niezależna od silnika.
MarkR

Odpowiedzi:

512

SQL NULL jest wyjątkowy i musisz to zrobić WHERE field IS NULL, ponieważ NULL nie może być niczym,

w tym siebie (tj .: NULL = NULL jest zawsze fałszem).

Zobacz Rule 3 https://en.wikipedia.org/wiki/Codd%27s_12_rules

Marc B.
źródło
24
Jest nieznany - nie fałszywy. SQL wykorzystuje logikę trójwartościową.
Martin Smith
38
NULL = NULL nie jest tak naprawdę FALSE - znów jest NULL. Ale to też nie jest PRAWDA, więc JEŻELI (NULL = NULL) nie zostanie wykonane.
Konerak,
1
patrz także @obe odpowiedź: WYBIERZ 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1, 1, 0
Thomas
Null nie tylko nie jest niczym, ale też nie jest niczym. Innymi słowy, select * from foo where bar <> "abc"będzie nie zwracać wierszy, gdzie bar jest null. To rzuciło mnie dzisiaj na pętlę. Dokumenty nazywają <>operator „nie równy”, ale tak naprawdę to „równa się operatorowi innemu niż”.
StackOverthrow
67
SELECT pid FROM planets WHERE userid IS NULL
Michael Pakhantsov
źródło
39

Ponieważ wszyscy otrzymują odpowiedzi, chcę dodać trochę więcej. Zetknąłem się również z tym samym problemem.

Dlaczego zapytanie nie powiodło się? Ty masz,

SELECT pid FROM planets WHERE userid = NULL;

To nie da oczekiwanego rezultatu, ponieważ z mysql doc

W SQL wartość NULL nigdy nie jest prawdziwa w porównaniu do jakiejkolwiek innej wartości, nawet NULL. Wyrażenie zawierające NULL zawsze wytwarza wartość NULL, chyba że w dokumentacji podano inaczej dla operatorów i funkcji zaangażowanych w wyrażenie.

Podkreśl moje.

Aby wyszukać wartości kolumn NULL, nie można użyć expr = NULLtestu. Poniższa instrukcja nie zwraca wierszy, ponieważ expr = NULLnigdy nie jest prawdziwa dla żadnego wyrażenia

Rozwiązanie

SELECT pid FROM planets WHERE userid IS NULL; 

Aby to sprawdzić NULL, użyj operatorów IS NULLi IS NOT NULL.

Aniket Kulkarni
źródło
11

Informacje z http://w3schools.com/sql/sql_null_values.asp :

1) Wartości NULL oznaczają brak nieznanych danych.

2) Domyślnie kolumna tabeli może zawierać wartości NULL.

3) Wartości NULL są traktowane inaczej niż inne wartości

4) Nie można porównać wartości NULL i 0; nie są równoważne.

5) Nie można przetestować wartości NULL za pomocą operatorów porównania, takich jak =, <lub <>.

6) Zamiast tego będziemy musieli użyć operatorów IS NULL i IS NOT NULL

W razie problemu:

SELECT pid FROM planets WHERE userid IS NULL
minhas23
źródło
7

Miał ten sam problem, w którym zapytanie:

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

nie zwrócił żadnych wartości. Wygląda na problem z MyISAM, a to samo zapytanie dotyczące danych w InnoDB zwróciło oczekiwane wyniki.

Poszedł z:

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

Zwrócono wszystkie oczekiwane wyniki.

RichKenny
źródło
5
SELECT pid FROM planets WHERE userid is null;
użytkownik
źródło
0

Miałem ten sam problem podczas konwersji baz danych z Access na MySQL (używanie vb.net do komunikacji z bazą danych).

Musiałem ocenić, czy pole (typ pola varchar (1)) było puste.

To oświadczenie zadziałało w moim scenariuszu:

SELECT * FROM [table name] WHERE [field name] = ''
użytkownik2406670
źródło
1
Jeśli to zadziałało, domyślnym ustawieniem dla twojego varchara (1) jest „” niż zero, dlatego nie ma związku z tym pytaniem.
さ り げ な い 告白