Ícone do site dfilitto

Dominando a Cláusula WHERE no SQL: Do Básico ao HAVING

Curso gratuito - Como trabalhar com o Banco de dados MySQL

No mundo do SQL, buscar dados é apenas metade da batalha. A outra metade, e talvez a mais importante, é buscar os dados certos. É aqui que entra a cláusula WHERE, a principal ferramenta de filtragem do seu arsenal.

A cláusula WHERE permite que você especifique exatamente quais linhas você quer que sua consulta SELECT retorne. Sem ela, você traria todos os dados da tabela. Com ela, você ganha precisão cirúrgica.

Neste guia, vamos explorar desde os operadores mais básicos da cláusula WHERE até a confusão comum com funções como SUM e MAX, e como usar a cláusula HAVING para resolver isso.

Preparando o Ambiente: Nossa Tabela de Exemplo

Para todos os exemplos, vamos usar uma tabela simples chamada Produtos em um banco de dados MySQL.

SQL

/* Script de criação da tabela para testes */
CREATE TABLE Produtos (
    ID INT PRIMARY KEY AUTO_INCREMENT,
    Nome VARCHAR(100),
    Categoria VARCHAR(50),
    Preco DECIMAL(10, 2),
    Estoque INT
);

INSERT INTO Produtos (Nome, Categoria, Preco, Estoque) VALUES
('Mouse Gamer', 'Eletrônicos', 150.00, 10),
('Teclado Mecânico', 'Eletrônicos', 350.00, 5),
('Monitor 24"', 'Eletrônicos', 1200.00, 3),
('Café 1kg', 'Alimentos', 30.00, 25),
('Arroz 5kg', 'Alimentos', 25.00, 50),
('Sabão em Pó', 'Limpeza', 15.00, 40),
('Headset', 'Eletrônicos', 250.00, 8);

Parte 1: Os Operadores Essenciais do WHERE

A sintaxe básica é sempre SELECT colunas FROM tabela WHERE condicao. Vamos ver as condições mais comuns.

1. Igualdade (=) e Diferença (!= ou <>)

Usados para buscar valores exatos ou para excluir valores exatos.

SQL

-- Buscar todos os produtos da categoria 'Alimentos'
SELECT * FROM Produtos
WHERE Categoria = 'Alimentos';

-- Buscar todos os produtos que NÃO são da categoria 'Eletrônicos'
SELECT * FROM Produtos
WHERE Categoria != 'Eletrônicos';

2. Comparações Numéricas (>, <, >=, <=)

Essencial para filtrar por números (como preços e quantidades) ou datas.

SQL

-- Buscar produtos que custam mais de R$ 100,00
SELECT Nome, Preco FROM Produtos
WHERE Preco > 100;

-- Buscar produtos com 10 ou menos itens em estoque
SELECT Nome, Estoque FROM Produtos
WHERE Estoque <= 10;

3. BETWEEN: Filtrando Intervalos

O BETWEEN é uma forma limpa de verificar se um valor está dentro de um intervalo (incluindo os valores limite).

SQL

-- Buscar produtos com preço entre R$ 100,00 e R$ 300,00
SELECT Nome, Preco FROM Produtos
WHERE Preco BETWEEN 100 AND 300;

-- Resultado: 'Mouse Gamer' (150.00) e 'Headset' (250.00)

4. IN: Verificando em uma Lista

O IN é perfeito para verificar se um valor corresponde a qualquer um dos itens em uma lista.

SQL

-- Buscar produtos das categorias 'Alimentos' ou 'Limpeza'
SELECT * FROM Produtos
WHERE Categoria IN ('Alimentos', 'Limpeza');

5. LIKE: Buscando Padrões de Texto

O LIKE é usado para buscas em texto (strings) onde você não sabe o valor exato. O símbolo % (porcentagem) atua como um coringa para “qualquer caractere”.

SQL

-- Buscar qualquer produto que comece com a palavra 'Mouse'
SELECT * FROM Produtos
WHERE Nome LIKE 'Mouse%';

-- Buscar qualquer produto que contenha a palavra 'Gamer'
SELECT * FROM Produtos
WHERE Nome LIKE '%Gamer%';

Parte 2: Combinando Condições com AND e OR

Você pode (e vai) precisar combinar várias condições.

SQL

-- Buscar produtos 'Eletrônicos' E que custam mais de R$ 300,00
SELECT * FROM Produtos
WHERE Categoria = 'Eletrônicos' AND Preco > 300;
-- Resultado: 'Teclado Mecânico' e 'Monitor 24"'

-- Buscar produtos 'Eletrônicos' OU que tenham mais de 30 em estoque
SELECT * FROM Produtos
WHERE Categoria = 'Eletrônicos' OR Estoque > 30;
-- Resultado: Todos os eletrônicos + Arroz + Sabão em Pó

Parte 3: A Grande Confusão: WHERE vs. HAVING (com SUM, MAX, COUNT)

Aqui está o ponto que gera mais dúvidas: “Como eu filtro usando um SUM ou MAX?”.

Muitos iniciantes tentam fazer isto:

SQL

-- ISSO GERA UM ERRO!
SELECT Categoria, SUM(Estoque)
FROM Produtos
WHERE SUM(Estoque) > 50;

O MySQL retornará um erro como “Invalid use of group function”.

Por que isso acontece? A Ordem de Execução

Pense na ordem lógica que o SQL processa sua consulta:

  1. FROM: Pega a tabela.
  2. WHERE: Filtra as linhas individuais.
  3. GROUP BY: Agrupa as linhas que sobraram.
  4. Funções de Agregação (SUM, MAX, etc.): Calculam os resultados para esses grupos.
  5. HAVING: Filtra os grupos já formados.
  6. SELECT: Escolhe as colunas finais.

O WHERE é executado antes do SUM(Estoque) ser calculado. Naquele momento, o SQL só vê linhas individuais, e não a soma de um grupo.

A Solução: GROUP BY e HAVING

Para filtrar o resultado de uma função de agregação, você deve:

  1. Usar GROUP BY para criar os grupos (ex: agrupar por Categoria).
  2. Usar HAVING para filtrar esses grupos.

Pense no HAVING como o “WHERE dos GROUP BY“.

Exemplo com SUM (Soma)

Queremos ver as categorias cuja SOMA total de estoque seja maior que 50.

SQL

SELECT
    Categoria,
    SUM(Estoque) AS EstoqueTotal
FROM
    Produtos
GROUP BY
    Categoria
HAVING
    EstoqueTotal > 50; -- Ou HAVING SUM(Estoque) > 50

-- Resultado: A categoria 'Alimentos' (com EstoqueTotal de 75)

Exemplo com MAX (Máximo)

Queremos ver as categorias onde o produto mais caro (MAX(Preco)) custa mais de R$ 1000,00.

SQL

SELECT
    Categoria,
    MAX(Preco) AS ProdutoMaisCaro
FROM
    Produtos
GROUP BY
    Categoria
HAVING
    ProdutoMaisCaro > 1000; -- Ou HAVING MAX(Preco) > 1000

-- Resultado: A categoria 'Eletrônicos' (com ProdutoMaisCaro de 1200.00)

Parte 4: Nível Avançado – Usando WHERE e HAVING Juntos

Sim, você pode usar os dois na mesma consulta! O WHERE filtra as linhas antes de agrupar, e o HAVING filtra os grupos depois.

Desafio: Queremos a média de preço (AVG) por categoria, mas considerando apenas produtos que temos em estoque (Estoque > 0). Além disso, só queremos ver categorias cuja média de preço seja maior que R$ 200,00.

SQL

SELECT
    Categoria,
    AVG(Preco) AS MediaDePreco
FROM
    Produtos
WHERE
    Estoque > 0    -- 1. O WHERE filtra as LINHAS primeiro (todos os nossos produtos têm estoque > 0)
GROUP BY
    Categoria      -- 2. Agrupa o que sobrou
HAVING
    MediaDePreco > 200; -- 3. O HAVING filtra os GRUPOS

-- Resultado: 'Eletrônicos' (Média de 487.50). 'Alimentos' e 'Limpeza' são filtrados pelo HAVING.

Resumo Rápido: WHERE vs. HAVING

Use esta tabela como sua “cola” rápida:

CaracterísticaWHEREHAVING
O que filtra?Linhas individuaisGrupos de linhas
Quando executa?Antes do GROUP BYDepois do GROUP BY
Aceita Funções?Não (ex: SUM, MAX)Sim (ex: SUM, MAX)

Sair da versão mobile