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

  1. CREATE TABLE e INSERT configuram uma tabela orders com quatro linhas cobrindo totais e datas diferentes.
  2. WHERE total BETWEEN 50 AND 150 mantém apenas as linhas em que total >= 50 AND total <= 150. Os dois limites são incluídos, então uma linha com exatamente 50 ou 150 também corresponderia.
  3. 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

AbordagemUse quando…
BETWEEN low AND highO intervalo é contínuo e os dois extremos são inclusivos
>= low AND < highVocê 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 < highOs 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.