Menu

WHERE no SQLite: filtrar linhas com LIKE, IN e BETWEEN

Entenda como a cláusula WHERE filtra linhas no SQLite: operadores de comparação, AND/OR, LIKE, IN, BETWEEN e a famosa pegadinha do NULL.

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

Como filtrar linhas no SQLite com a cláusula WHERE

Um SELECT sem WHERE devolve todas as linhas da tabela. Quase nunca é isso que a gente quer. A cláusula WHERE no SQLite serve justamente para manter só as linhas que batem com uma condição — o SQLite percorre a tabela, avalia a condição em cada linha e fica apenas com aquelas em que o resultado é verdadeiro.

Três linhas voltam: Neuromancer, Hyperion e The Martian. A condição year > 1980 foi avaliada para cada linha, e só os registros que bateram com o filtro passaram.

O modelo mental é o seguinte: o WHERE funciona como um filtro entre o FROM e as colunas que você seleciona no SELECT. Tudo que for avaliado como verdadeiro passa adiante.

Operadores de comparação

O básico funciona como você imagina:

= para igualdade, != ou <> para "diferente", e <, <=, >, >= para ordenação. Comparações de strings usam os mesmos operadores — author = 'Asimov' casa exatamente, caractere por caractere.

Uma observação importante: no SQL, aspas simples delimitam literais de string. Aspas duplas são para identificadores (nomes de colunas ou tabelas). WHERE author = "Asimov" pode até funcionar no SQLite por motivos históricos, mas não é portável e pode falhar silenciosamente quando a "string" coincide com o nome de alguma coluna. Use sempre aspas simples.

AND, OR e parênteses: combinando múltiplas condições

Na prática, quase toda consulta combina várias condições. O AND exige que ambos os lados sejam verdadeiros; o OR exige que pelo menos um seja:

A primeira consulta filtra livros recentes e curtos. A segunda traz livros de qualquer um dos dois autores.

Quando você mistura AND e OR, a precedência costuma pegar muita gente desprevenida. O AND tem prioridade maior que o OR, então:

lê-se como Herbert OR (Gibson AND year > 1980) — ou seja, todos os livros do Herbert independentemente do ano, mais os livros do Gibson depois de 1980. Provavelmente não é isso que você quis dizer. Coloque sua intenção entre parênteses:

Na dúvida, coloque parênteses. O otimizador de consultas não liga, e a próxima pessoa que ler o código vai te agradecer.

NULL não se comporta como um valor

Essa é a pegadinha da cláusula WHERE que pega todo mundo pelo menos uma vez. NULL no SQL significa "desconhecido", e valores desconhecidos não podem ser comparados. coluna = NULL não é falso — o resultado é NULL, e o WHERE interpreta isso como "pule essa linha".

IS NULL e IS NOT NULL são os únicos operadores que testam NULL diretamente. Decore isso de uma vez por todas — qualquer outra comparação com NULL devolve NULL e descarta as linhas sem avisar.

A mesma regra vale para a negação. WHERE author != 'Asimov' não traz as linhas em que author IS NULL, porque NULL != 'Asimov' também é NULL. Se você quiser incluir os NULLs, peça de forma explícita: WHERE author != 'Asimov' OR author IS NULL.

IN e BETWEEN: atalhos que você vai usar todo dia

O IN verifica se um valor está em uma lista. É uma forma mais limpa de escrever uma sequência de ORs:

BETWEEN testa um intervalo, incluindo as duas pontas:

year BETWEEN 1980 AND 2000 é equivalente a year >= 1980 AND year <= 2000, só que mais enxuto. Vale lembrar de um detalhe: os dois limites são inclusivos. Se você precisa de limites exclusivos, escreva as comparações na mão mesmo.

Um aviso rápido sobre IN e NULL: um WHERE coluna NOT IN (1, 2, NULL) nunca vai retornar linha nenhuma, já que qualquer comparação com NULL resulta em NULL. Tire os NULLs da sua lista, ou trate eles à parte com IS NULL.

LIKE para busca por padrão no SQLite

O LIKE faz casamento de padrões em strings usando dois curingas:

  • % casa com qualquer sequência de caracteres (inclusive vazia).
  • _ casa com exatamente um caractere.

Por padrão, o LIKE do SQLite é case-insensitive para letras ASCII — ou seja, 'Dune' LIKE 'dune' retorna verdadeiro. Isso pega de surpresa quem vem do Postgres, onde o LIKE diferencia maiúsculas de minúsculas e existe o ILIKE para o caso insensível. (No SQLite não tem ILIKE.)

Se você precisar de uma comparação que diferencie maiúsculas e minúsculas, dá pra resolver de duas formas. A primeira é alternar o pragma global:

PRAGMA case_sensitive_like = ON;

Ou use GLOB, que sempre diferencia maiúsculas de minúsculas e trabalha com curingas no estilo Unix (* para qualquer sequência e ? para um único caractere):

GLOB 'd*' não casaria com nada aqui — maiúsculas e minúsculas fazem diferença.

Filtrando datas com WHERE

O SQLite guarda datas como texto (geralmente no formato YYYY-MM-DD ou ISO 8601 completo). Por causa disso, comparações de string acabam funcionando como comparações de data — desde que você mantenha o padrão ISO:

Como '2024-06-01' < '2024-11-08' vale tanto na comparação de strings quanto de datas, essas consultas funcionam direitinho. Mas se você guardar datas em qualquer outro formato ('15/01/2024', 'Jan 15 2024'), as comparações vão dar resultado errado sem avisar. Use sempre o padrão ISO 8601 — seu eu do futuro agradece.

Para contas mais complicadas com datas (extrair o ano, comparar com "hoje"), o SQLite oferece as funções date(), strftime() e julianday(). Vamos ver tudo isso no capítulo sobre data e hora.

Juntando tudo na cláusula WHERE

Veja uma consulta que combina vários desses recursos de uma vez só:

Leia linha a linha: manter as linhas com ano conhecido, dentro do intervalo, de um dos dois autores ou com texto longo o suficiente, e que não sejam rascunho. É a cláusula WHERE fazendo o que faz de melhor — combinando condições pequenas e legíveis em filtros precisos.

Dois hábitos que vale a pena manter:

  • Coloque cada condição indentada em sua própria linha. Cláusulas WHERE longas viram uma bagunça ilegível quando ficam numa linha gigante.
  • Comente a intenção quando a condição não for óbvia. Um -- exclui rascunhos é um seguro barato.

Próximo passo: operadores e NULL em detalhe

A cláusula WHERE é, na maior parte do tempo, operadores aplicados a colunas — e o NULL muda silenciosamente o comportamento de cada um deles. A próxima página entra a fundo no conjunto de operadores do SQLite: aritméticos, concatenação de strings com ||, a família IS, lógica de três valores — para que essas surpresas deixem de ser surpresa.

Perguntas frequentes

Como funciona a cláusula WHERE no SQLite?

O WHERE filtra as linhas de uma consulta avaliando uma condição linha a linha. As linhas em que a condição é verdadeira ficam; as que dão falso ou NULL são descartadas. Ele vem logo depois do FROM: SELECT ... FROM tabela WHERE condicao.

Como combinar várias condições no WHERE do SQLite?

Use AND e OR. O AND exige que os dois lados sejam verdadeiros; o OR precisa só de um. Como o AND tem precedência maior que o OR, vale a pena usar parênteses para deixar tudo explícito: WHERE (a OR b) AND c.

Por que WHERE coluna = NULL não funciona no SQLite?

NULL significa "valor desconhecido", então qualquer comparação com = ou != devolve NULL em vez de verdadeiro ou falso — e o WHERE só mantém linhas quando a condição é verdadeira. Use IS NULL e IS NOT NULL, que são os únicos operadores que testam NULL diretamente.

O LIKE do SQLite diferencia maiúsculas de minúsculas?

Por padrão, o LIKE é case-insensitive para caracteres ASCII — ou seja, 'Hello' LIKE 'hello' é verdadeiro. Se quiser comparação sensível ao caso, ative PRAGMA case_sensitive_like = ON; ou use o GLOB, que sempre diferencia maiúsculas/minúsculas e usa curingas no estilo Unix (* e ?).

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR