WHERE: só as linhas necessárias
O que você vai aprender
- entender que o
WHEREfiltra linhas, e não colunas; - distinguir a escolha de colunas pelo
SELECTda seleção de linhas peloWHERE; - escrever condições com os operadores de comparação:
=,<>,<,>,<=,>=; - combinar condições com
ANDeOR; - posicionar corretamente os parênteses em condições mistas;
- entender por que o
ANDé avaliado antes doOR; - encontrar erros lógicos silenciosos nas consultas;
- entender por que
NULLnão se verifica com= NULL.
WHERE: o feixe que deixa passar só as linhas necessárias
Atrás do terminal fica o depósito: escuridão por milhares de linhas.
Iluminar tudo de uma vez não adianta: dados demais cegam tanto quanto o escuro.
O arquivista não precisa de um refletor, e sim de um feixe. Estreito, bem apontado, honesto. Um feixe que não mostra tudo de uma vez, mas ajuda a achar só o que interessa.
Em SQL, esse feixe se chama WHERE.
O comando SELECT responde à pergunta:
O que mostrar no resultado?
Já o WHERE responde a outra pergunta:
Quais linhas podem entrar no resultado?
Essa diferença é muito importante.
Veja esta consulta, por exemplo:
SELECT name, price
FROM products;
Ela diz ao banco:
Pegue a tabela
productse mostre dela as colunasnameeprice.
Mas, se você acrescentar o WHERE:
SELECT name, price
FROM products
WHERE price > 4000;
o sentido muda:
Pegue a tabela
products, confira cada linha e mostre só os itens cujo preço é maior que 4000.
O WHERE não escolhe colunas.
O WHERE escolhe linhas.
As colunas que vão aparecer no resultado são definidas na parte do SELECT.
E as linhas que vão chegar ao resultado são definidas na parte do WHERE.

WHERE é um feixe no depósito escuro: cada linha é testada pela condição, e poucas chegam à saída.A estrutura básica de uma consulta com WHERE
Normalmente, uma consulta com filtragem tem esta cara:
SELECT column_1, column_2
FROM table_name
WHERE condition;
Vamos por partes:
SELECT name, price
FROM products
WHERE price > 4000;
SELECT name, price— quais dados mostrar no resultado;FROM products— de qual tabela vêm as linhas;WHERE price > 4000— quais linhas manter;price > 4000— a condição verificada em cada linha.
O banco percorre mentalmente as linhas da tabela products e, para cada uma, faz a pergunta:
Esta linha tem
price > 4000?
Se a resposta for TRUE, a linha entra no resultado.
Se a resposta for FALSE, a linha é descartada.
Importante: o WHERE não apaga linhas da tabela.
Ele apenas deixa de mostrar, no resultado daquela consulta, as linhas que não se encaixam.
A tabela continua exatamente como era.
WHERE: a condição é avaliada linha por linha, e só entram no resultado as linhas cuja resposta é TRUE.Toda consulta devolve uma nova tabela de resultado
Quando você escreve uma consulta SQL, o banco não se limita a “mostrar um pedaço da tabela”.
Ele monta o resultado da consulta — uma tabela temporária, que é o que você vê na tela.
Por exemplo:
SELECT name, price
FROM products
WHERE price > 4000;
pode devolver este resultado:
| name | price |
|---|---|
| Projetor holográfico | 7800 |
| Neurointerface de treinamento | 12500 |
| Escâner portátil de matéria | 5600 |
Essa tabela de resultado tem apenas duas colunas: name e price.
Mas a filtragem aconteceu pela coluna price.
Ou seja, a coluna price cumpriu dois papéis ao mesmo tempo:
- participou da verificação da condição;
- apareceu no resultado.
Mas nem sempre é assim.
Dá para filtrar linhas por uma coluna que você não mostra no resultado:
SELECT name, price
FROM products
WHERE stock < 60;
Aqui o resultado traz apenas name e price, mas o banco continua usando a coluna stock para decidir quais linhas manter.
Isso é normal e muito comum.
O WHERE pode verificar uma coluna mesmo que ela não esteja no SELECT.
Operadores de comparação
No WHERE, os operadores de comparação são os mais usados.
Eles ajudam a verificar se o valor de uma linha se encaixa na condição desejada.
Os principais operadores:
| Operador | Significado | Exemplo |
|---|---|---|
= | igual a | category = 'Книги' |
<> | diferente de | status <> 'cancelled' |
> | maior que | price > 4000 |
< | menor que | stock < 60 |
>= | maior ou igual a | rating >= 4.5 |
<= | menor ou igual a | stock <= 10 |
Exemplos:
SELECT name, category
FROM products
WHERE category = 'Книги';
Mostra apenas os itens da categoria “Livros”.
SELECT name, status
FROM orders
WHERE status <> 'cancelled';
Mostra os pedidos cujo status é diferente de cancelled.
SELECT name, price
FROM products
WHERE price <= 1500;
Mostra os itens com preço de 1500 ou menos.
Repare: os valores de texto vão entre aspas simples:
WHERE category = 'Книги'
Já os números costumam ir sem aspas:
WHERE price > 4000
Não escreva assim:
WHERE category = Книги
Para o SQL, a palavra Книги sem aspas não parece um texto, e sim o nome de uma coluna ou de outro objeto. Por isso o texto precisa de aspas.
Importante: em SQL, a igualdade é verificada com um único sinal =.
Certo:
WHERE status = 'paid'
Errado:
WHERE status == 'paid'
Em algumas linguagens de programação, a comparação se escreve com ==, mas em SQL a forma padrão é =.
Várias condições: AND e OR
Muitas vezes, uma condição só não basta.
Um comprador, por exemplo, pode querer encontrar não só itens caros, mas itens caros que estão acabando.
É para isso que servem os operadores lógicos:
AND— “e”;OR— “ou”.
AND: todas as condições precisam ser atendidas
SELECT name, price, stock
FROM products
WHERE price > 4000 AND stock < 60;
Essa consulta mostra apenas as linhas em que, ao mesmo tempo:
price > 4000;stock < 60.
Ou seja, o item precisa ser caro e ter pouco estoque.
Se o preço for maior que 4000, mas o estoque for 200, a linha não passa.
Se o estoque for menor que 60, mas o preço for 900, a linha também não passa.
O AND é rigoroso.
Ele deixa a linha passar somente quando todas as condições são atendidas.
OR: basta uma condição
SELECT name, category, price
FROM products
WHERE category = 'Книги' OR category = 'Игрушки';
Essa consulta mostra os itens que pertencem à categoria “Livros” ou à categoria “Brinquedos”.
A linha passa se pelo menos uma condição for atendida:
- o item é da categoria “Livros”;
- o item é da categoria “Brinquedos”.
O OR é mais amplo que o AND.
Ele deixa passar mais linhas, porque basta uma das condições ser atendida.
Análise da consulta do exemplo
Vamos olhar a consulta com mais atenção:
SELECT name, price, stock
FROM products
WHERE price > 4000 AND stock < 60
ORDER BY price DESC;
Ela faz quatro coisas:
- Pega as linhas da tabela
products. - Verifica cada linha com a condição:
price > 4000 AND stock < 60
- Mantém apenas as linhas em que a condição é verdadeira.
- Mostra as colunas
name,priceestocke ordena o resultado por preço, do maior para o menor.
Em linguagem de gente, a consulta diz:
Mostre o nome, o preço e o estoque dos itens da tabela
products,
mas só dos que custam mais de 4000 e têm menos de 60 unidades em estoque,
e ordene do mais caro para o mais barato.
Uma consulta assim já não parece um exercício, e sim uma ferramenta analítica de trabalho.
Ela responde a uma pergunta concreta do negócio:
Quais itens caros podem acabar em breve?
No Vault-9, linhas assim não são apenas números.
São sinais.
Lá em 2024, um comprador olhava para uma saída dessas e entendia: era preciso repor o estoque antes que os clientes vissem a prateleira vazia.
Como o banco “pensa” ao executar uma consulta
Quem está começando costuma ler o SQL de cima para baixo e achar que o banco executa o SELECT primeiro.
Mas, logicamente, a consulta funciona de outro jeito.
Para a consulta:
SELECT name, price
FROM products
WHERE price > 4000
ORDER BY price DESC;
a ordem lógica aproximada é esta:
-
FROM products
O banco entende de qual tabela vêm as linhas. -
WHERE price > 4000
O banco verifica cada linha e mantém só as que se encaixam. -
SELECT name, price
O banco monta as colunas do resultado. -
ORDER BY price DESC
O banco ordena as linhas finais.
Ou seja, o WHERE age antes de o resultado final ser montado.
É exatamente por isso que dá para filtrar linhas por uma coluna que você não mostra no SELECT:
SELECT name
FROM products
WHERE price > 4000;
O resultado vai trazer apenas name, mas o banco continua usando price na etapa de filtragem.
Exemplo da história: os pedidos que aguardam
O feixe do WHERE não ilumina só produtos e números.
Na tabela orders há pedidos com status pending — “aguardando”.
SELECT id, customer_name, status
FROM orders
WHERE status = 'pending';
Uma consulta dessas mostra apenas os pedidos que ainda esperam para ser processados.
Num sistema comum, isso é uma tarefa de rotina para um gerente: descobrir por que o pedido travou.
Mas, no arquivo da velha Terra, essas linhas soam diferente.
Alguns pedidos aguardam há quase cento e sessenta anos.
Ninguém nunca vai recebê-los.
Mas os dados ainda guardam honestamente o status:
pending
aguardando.
QUERY:
pendingaqui quer dizer “aguardando para sempre”. Não se demore nisso, cadete. Continue iluminando.
Precedência de AND e OR: a armadilha que fica calada
Enquanto o WHERE usa só AND ou só OR, tudo costuma ficar claro.
Por exemplo:
WHERE price > 4000 AND stock < 60
Ou:
WHERE category = 'Книги' OR category = 'Игрушки'
Mas os problemas começam quando AND e OR se misturam numa mesma condição.
Os operadores lógicos têm uma ordem de precedência:
NOTANDOR
Isso quer dizer que o AND liga as condições com mais força do que o OR.
Veja esta consulta:
-- Queríamos: itens de Livros ou Brinquedos mais baratos que 1500
SELECT name, category, price
FROM products
WHERE category = 'Книги' OR category = 'Игрушки' AND price < 1500;
À primeira vista, parece que a consulta significa:
Mostre os livros ou os brinquedos que custam menos de 1500.
Mas o SGBD vai lê-la de outro jeito:
WHERE category = 'Книги'
OR (category = 'Игрушки' AND price < 1500)
A condição de preço price < 1500 «grudou» só nos brinquedos.
No resultado vão entrar:
- todos os livros, até os caros;
- só os brinquedos que custam menos de 1500.
Ou seja, um livro caro também vai aparecer no resultado, mesmo que a intenção fosse selecionar apenas os itens baratos.
A consulta está sintaticamente correta.
O banco de dados não vai acusar erro.
Ele vai executar honestamente o que está escrito.
O problema é que o que está escrito não é o que se queria dizer.
É isso que chamamos de erro lógico silencioso.
Por que isso é perigoso: linha por linha
Suponha que a tabela tenha estes itens:
| name | category | price |
|---|---|---|
| Algoritmos na prática | Livros | 1690 |
| Drone infantil | Brinquedos | 1200 |
| Kit da estação orbital | Brinquedos | 2300 |
| Cabo de alimentação | Eletrônicos | 700 |
A consulta sem parênteses:
SELECT name, category, price
FROM products
WHERE category = 'Книги' OR category = 'Игрушки' AND price < 1500;
O banco vai ler assim:
WHERE category = 'Книги'
OR (category = 'Игрушки' AND price < 1500)
Vamos conferir as linhas:
Linha 1: “Algoritmos na prática”
category = 'Книги' → TRUE
Como a primeira parte já é TRUE, a linha passa.
O preço de 1690 não atrapalha, porque a condição de preço vale só para os brinquedos.
Linha 2: “Drone infantil”
category = 'Игрушки' → TRUE
price < 1500 → TRUE
As duas partes depois do AND são verdadeiras, e a linha passa.
Linha 3: “Kit da estação orbital”
category = 'Игрушки' → TRUE
price < 1500 → FALSE
Depois do AND o resultado é FALSE, e a linha não passa.
Linha 4: “Cabo de alimentação”
category = 'Книги' → FALSE
category = 'Игрушки' → FALSE
A linha não passa.
O erro final: um livro caro entrou no resultado, embora a nossa intenção fosse trazer itens mais baratos que 1500.
Os parênteses devolvem o sentido à consulta
Se queremos selecionar itens das categorias “Livros” ou “Brinquedos”, mas todos eles precisam custar menos de 1500, é preciso agrupar as categorias explicitamente:
SELECT name, category, price
FROM products
WHERE (category = 'Книги' OR category = 'Игрушки')
AND price < 1500;
Agora a condição se lê assim:
Primeiro verifique que o item é um livro ou um brinquedo.
Depois verifique que o preço dele é menor que 1500.
Os parênteses deixam claro, para o banco e para quem lê, como a condição deve ser entendida.
Regra de arquivista:
Sempre que
ANDeORaparecerem juntos no mesmoWHERE, use parênteses.
Mesmo quando a precedência “já parece óbvia”.
O não detecta erro de lógica.
Mas quem for ler sua consulta daqui a cem anos vai agradecer.
Um erro silencioso é mais perigoso que um erro de sintaxe.
Se você escrever uma consulta com erro de sintaxe, o banco para e avisa:
“Não consigo executar isto”.
Mas, se você errar a lógica do WHERE, o banco pode executar a consulta sem reclamar nada.
Você vai receber uma tabela.
Ela vai parecer plausível.
Vai ter linhas.
Talvez até muitas linhas.
Mas não serão as linhas que você queria.
Por isso, em análise de dados e em teste de consultas, é importante verificar não só que a consulta roda, mas também que ela devolve o que você realmente queria.
Uma armadilha importante: NULL não se testa com =
O SQL tem um valor especial: NULL.
NULL não significa zero, nem string vazia, nem a palavra “não”.
NULL significa:
o valor é desconhecido ou está ausente.
Um pedido, por exemplo, pode ainda não ter data de entrega:
delivered_at = NULL
Quem está começando costuma tentar encontrar essas linhas assim:
SELECT id, status, delivered_at
FROM orders
WHERE delivered_at = NULL;
Mas essa verificação está errada.
No SQL não dá para comparar um valor com NULL usando =.
Porque NULL é justamente o desconhecido.
O jeito certo é este:
SELECT id, status, delivered_at
FROM orders
WHERE delivered_at IS NULL;
E, se você precisa das linhas em que o valor está preenchido:
SELECT id, status, delivered_at
FROM orders
WHERE delivered_at IS NOT NULL;
A ideia principal:
- para valores comuns usamos
=,<>,<,>,<=,>=; - para
NULLusamosIS NULLeIS NOT NULL.
Ainda vamos tratar do NULL em detalhe, numa aula só dele, mas já vale guardar isto:
WHERE column = NULL é quase sempre um erro.
Detalhe profissional: só entram no resultado as linhas em que a condição do WHERE deu TRUE.
Se a condição deu FALSE, a linha não passa.
Se a condição deu por causa de um NULL, a linha também não passa.
Por isso o NULL pode influenciar a filtragem sem você perceber.
Erros comuns de quem está começando
Erro 1. Achar que o WHERE escolhe colunas
Ideia errada:
o
WHEREserve para escolher os campos que você quer.
Ideia certa:
o
WHEREserve para escolher as linhas que você quer.
Quem escolhe as colunas é o SELECT.
SELECT name, price
FROM products
WHERE category = 'Книги';
Aqui:
SELECT name, priceescolhe as colunas;WHERE category = 'Книги'escolhe as linhas.
Erro 2. Escrever == no lugar de =
Errado:
WHERE status == 'paid'
Certo:
WHERE status = 'paid'
Erro 3. Esquecer as aspas em volta do texto
Errado:
WHERE status = paid
Certo:
WHERE status = 'paid'
Erro 4. Misturar AND e OR sem parênteses
Perigoso:
WHERE status = 'pending' OR status = 'paid' AND total > 5000;
Melhor:
WHERE (status = 'pending' OR status = 'paid')
AND total > 5000;
Erro 5. Testar NULL com =
Errado:
WHERE delivered_at = NULL
Certo:
WHERE delivered_at IS NULL
Erro 6. Colocar o WHERE depois do ORDER BY
Errado:
SELECT name, price
FROM products
ORDER BY price DESC
WHERE price > 4000;
Certo:
SELECT name, price
FROM products
WHERE price > 4000
ORDER BY price DESC;
Numa consulta comum, o WHERE vem depois do FROM, mas antes do ORDER BY.
Interview question
Pergunta de entrevista:
o que esta condição retorna?
WHERE a = 1 OR b = 2 AND c = 3
Resposta forte:
o AND liga com mais força que o OR, então a condição é lida assim:
WHERE a = 1 OR (b = 2 AND c = 3)
Ou seja, vão entrar no resultado:
- todas as linhas em que
a = 1; - mais as linhas em que valem ao mesmo tempo
b = 2ec = 3.
Se a intenção era outro agrupamento, os parênteses são necessários.
Na prática, em condições mistas vale sempre usar parênteses.
É uma defesa simples contra erros lógicos silenciosos.
WHERE faz?WHERE category = 'Книги' OR category = 'Игрушки' AND price < 1500
- Cabines com o pacote completo de comodidadesEASY
- Products from two warehousesEASY
- Catalog Without ArchiveEASY