NULL significa "desconhecido"
Todos os outros valores no SQLite representam algo concreto — um número, uma string, um blob. Já o NULL é diferente: ele funciona como um marcador para um valor ausente ou desconhecido. É essa ideia simples que explica todo o comportamento estranho do NULL nas consultas.
Vamos montar uma tabelinha para brincar:
Duas colunas aceitam nulos. Boris não tem e-mail. Cleo não tem idade. Dan não tem nenhum dos dois. O resto da página é sobre como consultar linhas desse tipo sem cair em pegadinhas.
Por que = e <> não funcionam com NULL
Seu primeiro instinto é escrever WHERE email = NULL. Parece fazer sentido. E não retorna nada:
Zero linhas — mesmo com Boris e Dan claramente tendo e-mails nulos. O motivo: comparar qualquer coisa com NULL resulta em NULL, e não em verdadeiro ou falso. O WHERE do SQLite só mantém as linhas em que a condição é verdadeira, e NULL não é verdadeiro. Então a linha acaba sendo descartada.
A mesma pegadinha aparece com <>:
Você esperaria que isso retornasse todo mundo, exceto a Ada. Mas só retorna a Cleo. O Boris e o Dan, cujos e-mails são NULL, somem do resultado — porque NULL <> 'ada@example.com' também é NULL, e não verdadeiro.
Essa é, de longe, a pegadinha mais clássica do SQL. Sempre que uma consulta "perde linhas" sem motivo aparente, desconfie de alguma coluna com valor nulo.
Use IS NULL e IS NOT NULL
A forma correta de comparar NULL no SQLite é com o operador IS. Diferente do =, ele entende valores nulos e devolve verdadeiro ou falso — nunca NULL:
A primeira consulta retorna Boris e Dan. A segunda retorna Ada e Cleo. IS NULL e IS NOT NULL são os dois operadores feitos sob medida para perguntar "esse valor está faltando?". Use-os sempre que tiver vontade de escrever = NULL ou <> NULL — porque, no SQLite, comparar com NULL usando = ou <> simplesmente não funciona.
Se você quer "diferente de Ada, incluindo os desconhecidos", combine as duas verificações de forma explícita:
Agora Boris, Cleo e Dan aparecem na consulta.
NULL se propaga em operações aritméticas e concatenação
A regra do "valor desconhecido" não vale só para comparações. Qualquer operação que envolva um NULL resulta em NULL:
next_year e doubled ficam nulos para Cleo e Dan. labelled_age também vem nulo para eles — concatenar uma string com NULL resulta em NULL, e não em 'Age: '. Se uma coluna pode ser nula e você precisa de um valor utilizável do outro lado, é preciso tratar isso. É aí que entram as duas próximas funções.
IFNULL: valor padrão com dois argumentos
IFNULL(a, b) devolve a, a menos que seja nulo — nesse caso, devolve b. É a forma mais direta de trocar um NULL por um valor padrão:
Boris e Dan ficam com (sem email). Cleo e Dan ficam com 0. Os dados originais não mudam — o IFNULL só reescreve o que aparece na saída.
O IFNULL aceita exatamente dois argumentos, sem exceção. Quando você precisa encadear mais alternativas, a ferramenta certa é o COALESCE.
COALESCE: o primeiro valor não-nulo vence
O COALESCE(a, b, c, ...) percorre os argumentos na ordem em que aparecem e devolve o primeiro que não for nulo. Pense nele como uma versão generalizada do IFNULL, com quantos fallbacks você quiser:
Para Ada e Cleo, o e-mail é utilizado. Já para Boris e Dan, o e-mail é nulo, então o SQLite cai no segundo argumento — um endereço sintetizado a partir do nome. Se esse valor também fosse nulo, a função recorreria a 'anônimo'.
O COALESCE é a escolha portável — todo banco SQL relevante o implementa da mesma forma. Já o IFNULL é um atalho do SQLite e do MySQL para o caso de apenas dois argumentos. Na dúvida entre IFNULL vs COALESCE, prefira o COALESCE; só use IFNULL quando você realmente tiver só dois argumentos e quiser o nome mais curto.
NULL no SQLite não é o mesmo que string vazia
Existe uma confusão clássica: muita gente trata NULL e '' como se fossem a mesma coisa. Não são.
'' é uma string de verdade que por acaso tem zero caracteres. Já NULL é a ausência de valor. length('') retorna 0; length(NULL) retorna o próprio NULL. E NULL = NULL resulta em NULL, não em 1 — e é justamente por isso que existe o IS NULL.
Se uma coluna pode guardar tanto '' quanto NULL, escolha qual dos dois significa "ausente" e mantenha o padrão. Misturar os dois obriga toda consulta a tratar dois casos, e cedo ou tarde você vai esquecer de um.
NULL em IN, NOT IN e DISTINCT
Tem mais alguns lugares onde o null aparece de surpresa.
Usar IN com uma lista que contém null pode trazer resultados inesperados, principalmente com NOT IN:
Você até espera receber todo mundo cuja idade não seja 25. Mas o resultado vem vazio. O SQLite expande NOT IN (25, NULL) para algo equivalente a age <> 25 AND age <> NULL, e age <> NULL sempre resulta em NULL — ou seja, a condição nunca é verdadeira. A solução é remover os nulos da lista (ou da coluna) antes de fazer a comparação.
Já o DISTINCT se comporta de outra forma: ele considera nulos como iguais entre si para efeito de deduplicação:
Você obtém três linhas: o email da Ada, o email da Cleo e um único NULL (consolidado a partir do Boris e do Dan). O mesmo vale para GROUP BY e UNION — eles tratam nulos como um único grupo, justamente o oposto do que o = faz. O SQL nem sempre é coerente quanto a isso; vale a pena saber em qual lado da linha cada operador se encaixa.
Checklist rápido para tratar valores nulos no SQLite
- Teste valores ausentes com
IS NULL/IS NOT NULL. Nunca use= NULL. - Qualquer aritmética, concatenação ou comparação envolvendo
NULLretornaNULL. - Use
COALESCE(a, b, c, ...)para substituir nulos por um valor de fallback. UseIFNULL(a, b)quando precisar só do atalho de dois argumentos. - String vazia
''não é a mesma coisa queNULL. Escolha um dos dois para representar "ausente" em cada coluna. NOT IN (..., NULL)é quase sempre um bug. Remova os nulos da lista antes.
A seguir: ordenando os resultados
Depois que você consegue filtrar as linhas corretamente — incluindo as que têm NULL —, o próximo passo é colocá-las em uma ordem útil. O ORDER BY é o tema da próxima página, e ele tem suas próprias regras sobre onde os nulos vão parar num resultado ordenado.
Perguntas frequentes
Por que coluna = NULL não funciona no SQLite?
coluna = NULL não funciona no SQLite?Porque NULL significa "valor desconhecido", e qualquer comparação com algo desconhecido também resulta em desconhecido — não em verdadeiro. Ou seja, WHERE col = NULL não retorna nenhuma linha, mesmo que existam linhas com a coluna nula. O certo é usar WHERE col IS NULL. A mesma lógica vale para <>: troque por IS NOT NULL.
Qual a diferença entre IFNULL e COALESCE no SQLite?
O IFNULL(a, b) aceita exatamente dois argumentos: devolve a, ou b caso a seja nulo. Já o COALESCE(a, b, c, ...) aceita quantos argumentos você quiser e retorna o primeiro que não for nulo. Pense no IFNULL como um atalho para dois valores; o COALESCE é a versão geral, e ainda por cima é portável entre praticamente todos os bancos SQL.
NULL é a mesma coisa que string vazia no SQLite?
Não. NULL é "ausência de valor", enquanto '' é uma string de tamanho zero — um valor real e conhecido. Por isso '' IS NULL retorna 0 (falso), e length('') dá 0, mas length(NULL) dá NULL. Se a sua coluna aceita os dois, ou você trata cada caso separadamente, ou normaliza tudo para um único formato.