Filtrando com WHERE
O que e o WHERE?
O WHERE e o filtro do SQL. Sem ele, toda consulta retorna todos os registros da tabela. Com ele, voce especifica exatamente quais linhas quer buscar. Pense no WHERE como um seguranca na porta: so passa quem cumpre as condicoes.
Operadores de comparacao
Os operadores basicos funcionam como na matematica:
-- Igual
SELECT * FROM usuarios WHERE idade = 25;
-- Diferente
SELECT * FROM usuarios WHERE status != 'inativo';
-- tambem funciona: WHERE status <> 'inativo'
-- Maior que
SELECT * FROM usuarios WHERE idade > 18;
-- Menor que
SELECT * FROM produtos WHERE preco < 50.00;
-- Maior ou igual
SELECT * FROM usuarios WHERE idade >= 21;
-- Menor ou igual
SELECT * FROM produtos WHERE estoque <= 10;
BETWEEN -- intervalo de valores
Busca valores dentro de um intervalo, incluindo os extremos:
-- Usuarios entre 18 e 30 anos (inclui 18 e 30)
SELECT * FROM usuarios WHERE idade BETWEEN 18 AND 30;
-- Equivalente a:
SELECT * FROM usuarios WHERE idade >= 18 AND idade <= 30;
-- Produtos com preco entre 10 e 100
SELECT * FROM produtos WHERE preco BETWEEN 10.00 AND 100.00;
IN -- lista de valores
Quando voce quer buscar varios valores especificos, use IN em vez de varios OR:
-- Usuarios de cidades especificas
SELECT * FROM usuarios WHERE cidade IN ('Sao Paulo', 'Rio de Janeiro', 'Curitiba');
-- Equivalente a (mas muito mais limpo):
SELECT * FROM usuarios
WHERE cidade = 'Sao Paulo'
OR cidade = 'Rio de Janeiro'
OR cidade = 'Curitiba';
-- Produtos de categorias especificas
SELECT * FROM produtos WHERE categoria_id IN (1, 3, 5, 7);
LIKE -- busca por padrao
O LIKE permite buscas parciais usando dois coringas:
%substitui zero ou mais caracteres_substitui exatamente um caractere
-- Nomes que comecam com 'Ana'
SELECT * FROM usuarios WHERE nome LIKE 'Ana%';
-- → Ana, Ana Paula, Anabela, Anastacia
-- Nomes que terminam com 'silva'
SELECT * FROM usuarios WHERE nome LIKE '%silva';
-- → Maria Silva, Joao Silva
-- Nomes que contem 'santos'
SELECT * FROM usuarios WHERE nome LIKE '%santos%';
-- → Carlos Santos, Ana Santos Lima
-- Emails do gmail
SELECT * FROM usuarios WHERE email LIKE '%@gmail.com';
-- Nomes com exatamente 3 letras
SELECT * FROM usuarios WHERE nome LIKE '___';
-- → Ana, Leo, Bia
-- Nomes que comecam com 'A' e tem 4 letras
SELECT * FROM usuarios WHERE nome LIKE 'A___';
-- → Anna, Aline nao (5 letras)
IS NULL e IS NOT NULL
NULL nao e um valor -- e a ausencia de valor. Por isso, nao funciona com =:
-- ERRADO: nunca vai funcionar!
SELECT * FROM usuarios WHERE telefone = NULL;
-- CERTO: use IS NULL
SELECT * FROM usuarios WHERE telefone IS NULL;
-- → Usuarios que nao informaram telefone
-- Usuarios que TEM telefone
SELECT * FROM usuarios WHERE telefone IS NOT NULL;
Operadores logicos: AND e OR
Combine condicoes para criar filtros mais precisos:
-- AND: TODAS as condicoes devem ser verdadeiras
SELECT * FROM usuarios
WHERE idade >= 18
AND cidade = 'Sao Paulo'
AND status = 'ativo';
-- OR: pelo menos UMA condicao deve ser verdadeira
SELECT * FROM usuarios
WHERE cidade = 'Sao Paulo'
OR cidade = 'Rio de Janeiro';
-- Combinando AND e OR (use parenteses!)
SELECT * FROM usuarios
WHERE status = 'ativo'
AND (cidade = 'Sao Paulo' OR cidade = 'Curitiba');
No Prisma
// Comparacao simples
const adultos = await prisma.usuario.findMany({
where: { idade: { gte: 18 } }
})
// BETWEEN
const faixaEtaria = await prisma.usuario.findMany({
where: { idade: { gte: 18, lte: 30 } }
})
// IN
const cidades = await prisma.usuario.findMany({
where: { cidade: { in: ['Sao Paulo', 'Curitiba'] } }
})
// LIKE (contains, startsWith, endsWith)
const gmail = await prisma.usuario.findMany({
where: { email: { endsWith: '@gmail.com' } }
})
const busca = await prisma.usuario.findMany({
where: { nome: { contains: 'santos', mode: 'insensitive' } }
})
// IS NULL
const semTelefone = await prisma.usuario.findMany({
where: { telefone: null }
})
// AND (implicito -- todas as condicoes no mesmo objeto)
const filtro = await prisma.usuario.findMany({
where: {
idade: { gte: 18 },
status: 'ativo',
cidade: 'Sao Paulo'
}
})
// OR (explicito)
const ouCidade = await prisma.usuario.findMany({
where: {
OR: [
{ cidade: 'Sao Paulo' },
{ cidade: 'Curitiba' }
]
}
})
No Drizzle
import { eq, ne, gt, lt, gte, lte, between, inArray, like, isNull, isNotNull, and, or } from 'drizzle-orm'
// Comparacao simples
const adultos = await db.select().from(usuarios).where(gte(usuarios.idade, 18))
// BETWEEN
const faixa = await db.select().from(usuarios).where(between(usuarios.idade, 18, 30))
// IN
const cidades = await db.select().from(usuarios)
.where(inArray(usuarios.cidade, ['Sao Paulo', 'Curitiba']))
// LIKE
const gmail = await db.select().from(usuarios)
.where(like(usuarios.email, '%@gmail.com'))
// IS NULL
const semTel = await db.select().from(usuarios).where(isNull(usuarios.telefone))
// AND
const filtro = await db.select().from(usuarios).where(
and(
gte(usuarios.idade, 18),
eq(usuarios.status, 'ativo')
)
)
// OR
const ouCidade = await db.select().from(usuarios).where(
or(
eq(usuarios.cidade, 'Sao Paulo'),
eq(usuarios.cidade, 'Curitiba')
)
)
No Lucid (AdonisJS)
// Comparacao simples
const adultos = await Usuario.query().where('idade', '>=', 18)
// BETWEEN
const faixa = await Usuario.query().whereBetween('idade', [18, 30])
// IN
const cidades = await Usuario.query().whereIn('cidade', ['Sao Paulo', 'Curitiba'])
// LIKE
const gmail = await Usuario.query().where('email', 'LIKE', '%@gmail.com')
// IS NULL
const semTel = await Usuario.query().whereNull('telefone')
// IS NOT NULL
const comTel = await Usuario.query().whereNotNull('telefone')
// AND (encadeamento)
const filtro = await Usuario.query()
.where('idade', '>=', 18)
.where('status', 'ativo')
.where('cidade', 'Sao Paulo')
// OR
const ouCidade = await Usuario.query()
.where('cidade', 'Sao Paulo')
.orWhere('cidade', 'Curitiba')
// AND + OR combinados
const combo = await Usuario.query()
.where('status', 'ativo')
.where((query) => {
query.where('cidade', 'Sao Paulo').orWhere('cidade', 'Curitiba')
})
Exercicios
- Escreva uma query que busque todos os produtos com preco entre R$50 e R$200.
- Encontre usuarios cujo email termina com
@empresa.come que estejam com statusativo. - Busque pedidos que foram feitos em janeiro de 2024 (use BETWEEN com datas).
- Liste clientes que nao informaram telefone (IS NULL) mas que tem email cadastrado (IS NOT NULL).
- Reescreva a query do exercicio 2 usando Prisma, Drizzle e Lucid.
Referencias
Testa o que você leu
5 perguntas sobre esta aula. Errar aqui não custa nada - a explicação vem junto da correção.