BETWEEN, IN e LIKE: filtros especiais
1. Introdução aos Filtros Especiais
Filtros especiais são operadores SQL que ampliam a capacidade de filtragem da cláusula WHERE para além das comparações básicas (=, >, <). Enquanto filtros básicos comparam valores individuais, os especiais permitem trabalhar com intervalos, listas e padrões de texto.
Os três operadores que exploraremos neste artigo — BETWEEN, IN e LIKE — resolvem problemas comuns de forma mais elegante e eficiente que suas alternativas manuais. Compreendê-los é essencial para escrever consultas SQL produtivas e legíveis.
2. BETWEEN: Filtrando por Intervalos
O operador BETWEEN define um intervalo inclusivo de valores. Sua sintaxe é direta:
SELECT * FROM tabela
WHERE coluna BETWEEN valor_inicial AND valor_final;
Exemplo com números:
-- Funcionários com salário entre R$ 5.000 e R$ 10.000
SELECT nome, salario FROM funcionarios
WHERE salario BETWEEN 5000 AND 10000;
Exemplo com datas:
-- Pedidos realizados em janeiro de 2024
SELECT * FROM pedidos
WHERE data_pedido BETWEEN '2024-01-01' AND '2024-01-31';
Exemplo com texto:
-- Produtos cujo nome está entre 'A' e 'M' (alfabeticamente)
SELECT nome FROM produtos
WHERE nome BETWEEN 'A' AND 'M';
Cuidado importante: BETWEEN é inclusivo nos dois limites. A consulta acima com datas inclui pedidos de '2024-01-31 00:00:00', mas exclui pedidos feitos após esse horário. Para incluir o dia inteiro, use:
-- Alternativa segura para datas com timestamp
SELECT * FROM pedidos
WHERE data_pedido >= '2024-01-01' AND data_pedido < '2024-02-01';
3. IN: Filtrando por Múltiplos Valores Específicos
O operador IN verifica se um valor pertence a uma lista de valores especificados. Substitui múltiplas condições OR com muito mais clareza.
Sintaxe básica:
SELECT * FROM tabela
WHERE coluna IN (valor1, valor2, valor3);
Exemplo com números:
-- Clientes das regiões 1, 3 e 5
SELECT nome, regiao FROM clientes
WHERE regiao IN (1, 3, 5);
Exemplo com strings:
-- Pedidos com status específicos
SELECT * FROM pedidos
WHERE status IN ('PENDENTE', 'EM_TRANSITO', 'ENTREGUE');
Vantagem sobre ORs:
-- Versão com OR (menos legível)
SELECT * FROM produtos
WHERE categoria = 'ELETRÔNICOS' OR categoria = 'INFORMÁTICA' OR categoria = 'GAMES';
-- Versão com IN (mais clara e performática)
SELECT * FROM produtos
WHERE categoria IN ('ELETRÔNICOS', 'INFORMÁTICA', 'GAMES');
IN com subconsultas:
-- Clientes que já fizeram pedidos
SELECT nome FROM clientes
WHERE id IN (SELECT DISTINCT cliente_id FROM pedidos);
4. LIKE: Correspondência de Padrões em Texto
O operador LIKE permite buscas por padrões em strings usando dois caracteres curinga:
%— corresponde a qualquer sequência de caracteres (inclusive vazia)_— corresponde a exatamente um caractere
Busca por prefixo:
-- Produtos que começam com 'Smart'
SELECT * FROM produtos
WHERE nome LIKE 'Smart%';
-- Resultados: 'Smartphone', 'Smartwatch', 'Smart TV'
Busca por sufixo:
-- E-mails com domínio .com.br
SELECT email FROM usuarios
WHERE email LIKE '%.com.br';
Busca por padrão interno:
-- Nomes que contêm 'silva' em qualquer posição
SELECT nome FROM clientes
WHERE nome LIKE '%silva%';
Usando _ para posição exata:
-- CEPs com 8 dígitos onde o 5º é '0'
SELECT cep FROM enderecos
WHERE cep LIKE '____0___';
Diferença entre LIKE e =:
-- Busca exata (só encontra 'Maria')
SELECT * FROM clientes WHERE nome = 'Maria';
-- Busca aproximada (encontra 'Maria', 'Mariana', 'Maria José')
SELECT * FROM clientes WHERE nome LIKE 'Maria%';
5. Combinação de BETWEEN, IN e LIKE com Outros Filtros
Estes operadores podem ser combinados entre si e com outros filtros usando AND, OR e parênteses.
BETWEEN + AND + IN:
-- Pedidos caros de categorias específicas no último trimestre
SELECT * FROM pedidos
WHERE valor_total BETWEEN 1000 AND 5000
AND categoria IN ('ELETRÔNICOS', 'INFORMÁTICA')
AND data_pedido BETWEEN '2024-01-01' AND '2024-03-31';
LIKE combinado com operadores lógicos:
-- Clientes com nome começando com 'A' ou 'B', e e-mail corporativo
SELECT * FROM clientes
WHERE (nome LIKE 'A%' OR nome LIKE 'B%')
AND email LIKE '%@empresa.com';
Ordem de precedência e parênteses:
-- Sem parênteses: interpretação incorreta (OR tem menor precedência)
SELECT * FROM produtos
WHERE preco BETWEEN 100 AND 500
OR categoria = 'PROMOÇÃO' AND estoque > 0;
-- Com parênteses: lógica correta
SELECT * FROM produtos
WHERE (preco BETWEEN 100 AND 500
OR categoria = 'PROMOÇÃO')
AND estoque > 0;
6. Performance e Boas Práticas
Quando BETWEEN é vantajoso:
- Para intervalos contíguos,
BETWEENé mais legível e igualmente eficiente que>= AND <=. - Em índices, o otimizador trata
BETWEENcomo duas comparações, sem perda de performance.
Cuidados com LIKE e índices:
-- Usa índice (busca por prefixo) → eficiente
SELECT * FROM clientes WHERE nome LIKE 'Silva%';
-- Ignora índice (coringa no início) → full scan
SELECT * FROM clientes WHERE nome LIKE '%Silva%';
Para buscas com % no início, considere índices全文搜索 (full-text search) ou expressões regulares.
Alternativas ao LIKE:
-- ILIKE: case-insensitive (PostgreSQL)
SELECT * FROM clientes WHERE nome ILIKE 'maria%';
-- SIMILAR TO: expressões regulares simplificadas (SQL padrão)
SELECT * FROM clientes WHERE nome SIMILAR TO '(Sr|Sra).%';
-- Expressões regulares completas (PostgreSQL, MySQL 8+)
SELECT * FROM clientes WHERE nome ~ '^[A-Z].*silva$';
7. Exemplos Práticos e Casos de Erro Comum
Exemplo completo: relatório de pedidos
-- Pedidos de janeiro/2024, com valor entre R$ 200 e R$ 2000,
-- status 'ENTREGUE' ou 'EM_TRANSITO',
-- e cliente com nome contendo 'Santos'
SELECT p.id, p.data_pedido, p.valor_total, c.nome AS cliente
FROM pedidos p
JOIN clientes c ON p.cliente_id = c.id
WHERE p.data_pedido BETWEEN '2024-01-01' AND '2024-01-31'
AND p.valor_total BETWEEN 200 AND 2000
AND p.status IN ('ENTREGUE', 'EM_TRANSITO')
AND c.nome LIKE '%Santos%'
ORDER BY p.valor_total DESC;
Erros comuns e como evitá-los:
- BETWEEN com datas sem timezone:
```text
-- Erro: exclui pedidos das 00:00:01 às 23:59:59 do último dia
WHERE data BETWEEN '2024-01-01' AND '2024-01-31'
-- Correto: converte para date ou usa intervalo aberto
WHERE CAST(data AS DATE) BETWEEN '2024-01-01' AND '2024-01-31'
```
- IN com lista vazia:
```text
-- Erro: retorna 0 linhas, mas pode causar confusão em consultas dinâmicas
WHERE status IN ()
-- Correto: validar antes ou usar condicional
WHERE (1=0) -- ou ignorar o filtro se lista vazia
```
- LIKE com escape de caracteres especiais:
```text
-- Buscar produtos com '100%' no nome
-- Erro: % é interpretado como coringa
WHERE nome LIKE '%100%%'
-- Correto: usar ESCAPE
WHERE nome LIKE '%100\%%' ESCAPE '\'
```
Dicas de depuração:
- Teste filtros individualmente antes de combiná-los
- Use EXPLAIN ANALYZE para verificar se índices estão sendo usados
- Em bancos grandes, prefira LIKE 'prefixo%' a LIKE '%padrão%'
Referências
- Documentação oficial MySQL: Comparison Functions and Operators — Referência completa dos operadores BETWEEN, IN e LIKE no MySQL, com sintaxe e exemplos.
- PostgreSQL Documentation: Pattern Matching — Guia oficial sobre LIKE, SIMILAR TO e expressões regulares no PostgreSQL.
- SQL Server: LIKE (Transact-SQL) — Documentação da Microsoft sobre o operador LIKE, incluindo padrões e escape de caracteres.
- W3Schools SQL BETWEEN Operator — Tutorial prático com exemplos interativos de BETWEEN em diferentes tipos de dados.
- Mode Analytics: SQL IN Operator Tutorial — Explicação detalhada do IN com exemplos reais e comparação de performance com OR.
- SQLShack: Understanding the SQL BETWEEN Operator — Artigo técnico sobre nuances do BETWEEN, incluindo questões de timezone e performance.
- LearnSQL: How to Use LIKE in SQL — Guia completo sobre LIKE com exemplos de padrões complexos e dicas de otimização.