SQL BETWEEN: intervalos inclusivos de número e data
SQL BETWEEN filtra linhas cujo valor de coluna cai em um intervalo especificado, incluindo os dois limites. Ele substitui um par de comparações >= e <= por um único predicado, o que mantém cláusulas WHERE mais curtas quando o intervalo é inclusivo. BETWEEN funciona com números, datas e texto, mas intervalos de datas exigem cuidado extra com componentes de tempo.
Exemplo de SQL BETWEEN para filtrar intervalos
Saída:
A saída aparecerá aqui...
Saída:
+----------+-------+------------+
| customer | total | placed |
+----------+-------+------------+
| Ben | 120.5 | 2026-02-15 |
| Cara | 89.99 | 2026-02-20 |
+----------+-------+------------+
2 row(s)
Como este exemplo funciona
CREATE TABLEeINSERTconfiguram uma tabelaorderscom quatro linhas cobrindo totais e datas diferentes.WHERE total BETWEEN 50 AND 150mantém apenas as linhas em quetotal >= 50 AND total <= 150. Os dois limites são incluídos, então uma linha com exatamente 50 ou 150 também corresponderia.- Linhas com totais de 45.00 e 200.00 ficam fora do intervalo e são excluídas.
x BETWEEN y AND z é equivalente a x >= y AND x <= z. Se qualquer limite for NULL, o predicado é avaliado como desconhecido e a linha é filtrada.
O que é SQL BETWEEN?
SQL BETWEEN testa se um valor cai dentro de um intervalo inclusivo: column >= low AND column <= high. Para intervalos numéricos, a leitura é clara e o comportamento previsível. Alguns bancos de dados também oferecem BETWEEN SYMMETRIC, que inverte os limites quando eles estão em ordem inversa.
Erros comuns com SQL BETWEEN
Erro: usar BETWEEN para intervalos de timestamp.
Errado:
WHERE placed BETWEEN '2026-02-01' AND '2026-02-28'
Certo:
WHERE placed >= '2026-02-01' AND placed < '2026-03-01'
Por quê: se a coluna inclui hora, uma data final como '2026-02-28' normalmente corresponde apenas ao início desse dia. Use um intervalo semiaberto para capturar o dia inteiro.
Erro: inverter os limites e esperar resultados.
Errado:
WHERE total BETWEEN 150 AND 50
Certo:
WHERE total BETWEEN 50 AND 150
Por quê: no BETWEEN padrão, o primeiro limite precisa ser o menor valor. Se os limites forem invertidos, a condição não pode ser verdadeira.
BETWEEN vs IN vs operadores de comparação
| Abordagem | Use quando… |
|---|---|
BETWEEN low AND high | O intervalo é contínuo e os dois extremos são inclusivos |
>= low AND < high | Você precisa de um limite superior exclusivo (timestamps, paginação) |
IN (a, b, c) | Os valores são discretos, não um intervalo contínuo |
> low AND < high | Os dois extremos devem ser exclusivos |
Regra: prefira BETWEEN para intervalos numéricos inclusivos. Troque para comparações explícitas quando um limite precisar ser exclusivo, especialmente com datas. Use IN para um conjunto fixo de valores; BETWEEN corresponderia a valores indesejados nos espaços entre eles.
Notas de desempenho
BETWEEN é sargable: o otimizador de consultas o trata como >= AND <= e pode usar um índice B-tree na coluna filtrada. Envolver a coluna em uma função (DATE(col), LOWER(col)) impede o uso do índice; normalize os limites no lugar disso. Intervalos amplos ainda leem muitas linhas mesmo com índice, então a seletividade importa mais do que a escolha do operador.
FAQ
SQL BETWEEN é inclusivo ou exclusivo?
BETWEEN é inclusivo nos dois extremos. WHERE x BETWEEN 5 AND 10 retorna linhas em que x é 5, 6, 7, 8, 9 ou 10. Não existe uma variante exclusiva embutida; use > e < para limites exclusivos.
BETWEEN pode ser usado com valores de texto?
Sim. WHERE name BETWEEN 'A' AND 'M' retorna nomes que se ordenam dentro desse intervalo segundo a collation atual. Os resultados dependem das regras de collation e da sensibilidade a maiúsculas/minúsculas do banco de dados, então teste com sua configuração antes de depender de intervalos de texto em produção.
Por que BETWEEN perde registros na data final?
Quando a coluna armazena um datetime (data + hora), um limite superior como '2026-02-28' geralmente é tratado como o início desse dia. Qualquer linha posterior em 28 de fevereiro fica fora do intervalo. Use um intervalo semiaberto (>= start AND < next_day) para cobrir o dia inteiro.