MySQL: selecionando linhas onde uma coluna é nula


270

Estou com um problema em que, quando tento selecionar as linhas que possuem um NULL para uma determinada coluna, ele retorna um conjunto vazio. No entanto, quando olho para a tabela no phpMyAdmin, ele diz nulo para a maioria das linhas.

Minha consulta é mais ou menos assim:

SELECT pid FROM planets WHERE userid = NULL

Conjunto vazio toda vez.

Muitos locais disseram para garantir que não sejam armazenados como "NULL" ou "null" em vez de um valor real, e um disse para tentar procurar apenas um espaço ( userid = ' '), mas nenhum deles funcionou. Houve uma sugestão para não usar o MyISAM e o innoDB porque o MyISAM tem problemas para armazenar nulos. Mudei a tabela para o innoDB, mas agora sinto que o problema pode ser que ele ainda não é nulo devido à maneira como pode convertê-lo. Eu gostaria de fazer isso sem ter que recriar a tabela como innoDB ou qualquer outra coisa, mas se for necessário, certamente posso tentar isso.


1
O MyISAM não tem problemas para armazenar nulos. A semântica dos próprios NULLs deve ser independente do mecanismo.
MarkR

Respostas:


513

O SQL NULL é especial, e você precisa fazer WHERE field IS NULL, pois NULL não pode ser igual a nada,

incluindo a si próprio (ou seja: NULL = NULL é sempre falso).

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


25
É desconhecido - não é falso. O SQL usa três lógicas com valor.
Martin Smith

39
NULL = NULL não é realmente FALSE - é NULL novamente. Mas também não é VERDADEIRO, portanto, SE (NULL = NULL) não será executado.
Konerak

1
veja também @obe answer: SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL; -> 1, 1, 0
Thomas

Não apenas nulo não é igual a nada, como também não é igual a nada. Em outras palavras, select * from foo where bar <> "abc"se não retornar linhas onde bar é nulo. Isso me jogou para dar uma volta hoje. Os documentos chamam <>o operador "não é igual a", mas na verdade é o "é igual a algo diferente de" operador.
StackOverthrow


39

Como todas as respostas são dadas, quero acrescentar um pouco mais. Eu também havia enfrentado o mesmo problema.

Por que sua consulta falhou? Você tem,

SELECT pid FROM planets WHERE userid = NULL;

Isso não fornecerá o resultado esperado, porque no mysql doc

No SQL, o valor NULL nunca é verdadeiro em comparação com qualquer outro valor, mesmo NULL. Uma expressão que contém NULL sempre produz um valor NULL, a menos que indicado de outra forma na documentação para os operadores e funções envolvidas na expressão.

Ênfase minha.

Para procurar valores de coluna que sejam NULL, você não pode usar um expr = NULLteste. A instrução a seguir não retorna linhas, porque expr = NULLnunca é verdadeira para nenhuma expressão

Solução

SELECT pid FROM planets WHERE userid IS NULL; 

Para testar NULL, use o IS NULLe IS NOT NULLoperadores.



11

Informações de http://w3schools.com/sql/sql_null_values.asp :

1) Valores NULL representam dados desconhecidos ausentes.

2) Por padrão, uma coluna da tabela pode conter valores NULL.

3) Valores NULL são tratados de forma diferente de outros valores

4) Não é possível comparar NULL e 0; eles não são equivalentes.

5) Não é possível testar valores NULL com operadores de comparação, como =, <ou <>.

6) Teremos que usar os operadores IS NULL e IS NOT NULL

Portanto, no caso de seu problema:

SELECT pid FROM planets WHERE userid IS NULL

7

Teve o mesmo problema em que consulta:

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

não retornou valores. Parece ser um problema com o MyISAM e a mesma consulta nos dados no InnoDB retornou os resultados esperados.

Foi com:

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

Retornou todos os resultados esperados.



0

Eu tive o mesmo problema ao converter bancos de dados do Access para MySQL (usando vb.net para se comunicar com o banco de dados).

Eu precisava avaliar se um campo (tipo de campo varchar (1)) era nulo.

Esta declaração funcionou para o meu cenário:

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

1
Se isso funcionou para você, o padrão para o seu varchar (1) é '' em vez de nulo, portanto, não está relacionado a esta pergunta.
告白 り げ な い
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.