Menu

SQLite e NULL: IS NULL, COALESCE e IFNULL na prática

Entenda por que = e <> não funcionam com NULL no SQLite e aprenda a usar IS NULL, IS NOT NULL, COALESCE e IFNULL do jeito certo.

Esta página tem editores executáveis — edite, execute e veja a saída na hora.

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 NULL retorna NULL.
  • Use COALESCE(a, b, c, ...) para substituir nulos por um valor de fallback. Use IFNULL(a, b) quando precisar só do atalho de dois argumentos.
  • String vazia '' não é a mesma coisa que NULL. 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?

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)NULL. Se a sua coluna aceita os dois, ou você trata cada caso separadamente, ou normaliza tudo para um único formato.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR