BETWEEN, IN e limites inclusivos
Explore casos extremos de limites e veja como BETWEEN trata os pontos finais.
BETWEEN, IN e limites inclusivos é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Interview Prep inclui 4 aulas no total.
Por que os limites fazem candidatos perderem pontos
Filtros de intervalo e de conjunto parecem triviais, por isso os entrevistadores exploram os casos extremos. BETWEEN inclui os dois limites, IN oculta uma armadilha sutil com NULL, e os intervalos de datas são onde erros de um dia corrompem relatórios silenciosamente.
Esta lição explica exatamente como BETWEEN trata seus limites, quando IN é mais claro que sequências encadeadas de OR e o padrão de intervalo semiaberto que profissionais usam para datas.
BETWEEN é inclusivo nas duas extremidades
col BETWEEN a AND b é uma forma abreviada de col >= a AND col <= b. Ambos os limites são incluídos.
Assim, price BETWEEN 10 AND 20 retorna linhas em que o preço é exatamente 10 ou exatamente 20, além de todos os valores intermediários. A resposta errada mais comum em entrevistas é afirmar que o limite superior é excluído.
SELECT *
FROM products
WHERE price BETWEEN 10 AND 20;
-- equivalent to: price >= 10 AND price <= 20A ordem dos argumentos é importante
BETWEEN exige primeiro o valor inferior. col BETWEEN 20 AND 10 se expande para col >= 20 AND col <= 10, o que nunca pode ser verdadeiro; portanto, retorna zero linhas, e não um erro.
Esta é uma armadilha favorita: a consulta é executada sem problemas, não retorna nada, e a pessoa candidata presume que os dados estão vazios. Sempre coloque o limite menor primeiro.
SELECT *
FROM products
WHERE price BETWEEN 20 AND 10;
-- returns NOTHING, not an errorO erro de um dia no intervalo de datas
Quando se pede todo o mês de janeiro, muitas pessoas candidatas escrevem order_date BETWEEN '2024-01-01' AND '2024-01-31'. Se order_date for uma marca temporal, isso descarta tudo depois da meia-noite do dia 31, porque 2024-01-31 significa 2024-01-31 00:00:00.
Um pedido feito às 14h do dia 31 de janeiro é excluído. Com colunas puras de DATE, funciona, mas não se pode presumir o tipo.
SELECT *
FROM orders
WHERE order_date BETWEEN '2024-01-01' AND '2024-01-31';
-- silently excludes Jan 31 afternoon if order_date is a timestampA correção com intervalo semiaberto
O padrão profissional para datas é um intervalo semiaberto: maior ou igual ao início e estritamente menor que o próximo período. Ele funciona tanto para DATE quanto para TIMESTAMP e não exige conhecimento sobre a resolução temporal da coluna.
Observe que o limite superior é o primeiro dia de fevereiro, não o último dia de janeiro. Isso abrange todos os instantes de janeiro.
SELECT *
FROM orders
WHERE order_date >= '2024-01-01'
AND order_date < '2024-02-01';NOT BETWEEN
col NOT BETWEEN a AND b se expande para col < a OR col > b. Ele exclui ambas as extremidades e tudo que estiver entre elas.
Atenção: se col for NULL, NOT BETWEEN será avaliado como UNKNOWN, portanto as linhas com NULL serão excluídas, assim como ocorre com um BETWEEN simples. Valores NULL nunca satisfazem um teste de intervalo em nenhuma das duas direções.
SELECT *
FROM products
WHERE price NOT BETWEEN 10 AND 20;
-- price < 10 OR price > 20IN para verificar pertencimento a um conjunto
col IN (a, b, c) é uma forma abreviada de col = a OR col = b OR col = c. É a maneira clara de verificar se um valor pertence a um pequeno conjunto fixo.
A leitura é melhor do que a de uma sequência de OR e o problema de colocar parênteses por causa da precedência é eliminado, pois o teste do conjunto inteiro é um único predicado.
SELECT *
FROM orders
WHERE status IN ('pending', 'shipped', 'delivered');A armadilha de NULL com NOT IN
Esta é a pergunta sobre IN mais temida. Se a lista (ou subconsulta) usada por NOT IN contiver um único NULL, todo o predicado poderá ser avaliado como UNKNOWN e retornar zero linhas.
O motivo é o seguinte: x NOT IN (1, NULL) se transforma em x <> 1 AND x <> NULL, e x <> NULL nunca é verdadeiro; ele é UNKNOWN. O AND inteiro nunca pode ser verdadeiro.
SELECT *
FROM employees
WHERE manager_id NOT IN (SELECT id FROM managers);
-- returns NOTHING if any managers.id is NULLCorrigindo NOT IN
Duas correções robustas para a armadilha de NULL em NOT IN:
- Filtre os NULLs para fora da subconsulta com
WHERE id IS NOT NULL - Melhor ainda, reescreva como
NOT EXISTS, que lida corretamente com NULL por definição
Entrevistadores consideram NOT EXISTS a resposta de nível sênior porque contorna completamente a armadilha e frequentemente produz um plano melhor.
SELECT e.*
FROM employees e
WHERE NOT EXISTS (
SELECT 1 FROM managers m WHERE m.id = e.manager_id
);IN com uma subconsulta
IN aceita uma subconsulta que retorna uma coluna. WHERE customer_id IN (SELECT customer_id FROM vip) mantém as linhas cujo cliente pertence ao conjunto VIP.
O IN simples, e não NOT IN, é seguro quando há NULLs na subconsulta: um NULL na lista simplesmente nunca corresponde, mas não invalida as linhas que correspondem. A armadilha é específica de NOT IN.
SELECT *
FROM orders
WHERE customer_id IN (SELECT customer_id FROM vip_customers);IN com várias colunas usando construtores de linha
Uma pergunta comum de acompanhamento: como você compara mais de uma coluna ao mesmo tempo? Passe uma tupla a IN usando um construtor de linha — ele compara as colunas por posição e é muito mais claro do que encadear OR (a = .. AND b = ..).
- A leitura fica clara e o padrão se adapta a listas extensas de valores permitidos.
- Cada tupla deve listar as colunas na mesma ordem.
SELECT *
FROM orders
WHERE (customer_id, status) IN ((101, 'paid'), (102, 'shipped'));Verificação rápida
Lembre-se de como BETWEEN trata seus limites.
Resumo
Principais conclusões:
BETWEEN a AND binclui os dois limites; o limite inferior deve vir primeiro, ou você obterá zero linhas- Para intervalos de marcas temporais, use um intervalo semiaberto:
>= start AND < next_period INverifica o pertencimento a um conjunto de forma clara e é seguro com NULLsNOT INcom qualquerNULLna lista não retorna nada; reescreva comoNOT EXISTS
O tema recorrente é o seguinte: um filtro pode ser executado perfeitamente e ainda assim retornar silenciosamente as linhas erradas.
Perguntas Frequentes
A aula “BETWEEN, IN e limites inclusivos” é grátis?
Sim — o texto completo de “BETWEEN, IN e limites inclusivos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Interview Prep, atualize para CoddyKit PRO. O curso de SQL Interview Prep inclui 4 aulas no total.
O que vou aprender em “BETWEEN, IN e limites inclusivos”?
Explore casos extremos de limites e veja como BETWEEN trata os pontos finais. Você pratica SQL Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar SQL Interview Prep?
Nenhuma experiência prévia é necessária. SQL Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “BETWEEN, IN e limites inclusivos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de SQL Interview Prep?
Sim. Cada aula de SQL Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Precedência de AND/OR e uso de parênteses
- BETWEEN, IN e limites inclusivos
- LIKE, curingas e escape
- Filtrando por valores calculados