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
WHERElongas 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 ?).