SQL Avançado: Queries para Diagnóstico e Análise

Um guia prático com exemplos interativos de queries complexas para resolver problemas reais de negócio, como análise de churn, relatórios gerenciais e auditoria de dados.

Se o nosso primeiro artigo de SQL foi o "cinto de utilidades" com as ferramentas essenciais, este é o seu "dicionário avançado". Aqui, vamos explorar cenários mais complexos que QAs e BAs enfrentam no dia a dia, especialmente em ambientes com grande volume de dados, como em projetos de telecomunicações ou do setor bancário.

Cada exemplo abaixo foi projetado para resolver um problema de negócio específico, transformando dados brutos em insights valiosos.

Navegue pelos Comandos Avançados:

  1. 1. LEFT JOIN
  2. 2. HAVING
  3. 3. CASE
  4. 4. Window Functions
  5. 5. CTEs
  6. 6. Subqueries
  7. 7. UNION
  8. 8. Self-Join
  9. 9. Funções de Data
  10. 10. Pivot

1. LEFT JOIN: Encontrando Dados "Órfãos"

Enquanto o JOIN tradicional só mostra a combinação perfeita entre duas tabelas, o LEFT JOIN é mais inclusivo. Ele retorna todos os registros da tabela da esquerda, e preenche com NULL (vazio) caso não encontre um par na tabela da direita. É a query perfeita para responder: "Quais clientes nunca fizeram um pedido?".

SELECT c.nome, p.id_pedido FROM clientes c LEFT JOIN pedidos p ON c.id = p.id_cliente;

Tabelas Originais:

clientes (esquerda)
idnome
1Ana
2Bruno
3Carlos
pedidos (direita)
id_pedidoid_cliente
1012
1021

2. HAVING: O Filtro para Grupos

Se o WHERE filtra linhas individuais antes da agregação, o HAVING filtra os resultados de um grupo, depois que a agregação já aconteceu. Ele é sempre usado com GROUP BY. A pergunta muda de "quais clientes são de SP?" (WHERE) para "quais estados têm mais de 1 cliente?" (HAVING).

SELECT estado, COUNT(*) FROM clientes GROUP BY estado HAVING COUNT(*) > 1;

Tabela Agrupada (Antes do HAVING):

estadoCOUNT(*)
SP2
RJ2
MG1

3. CASE: O "Se-Então-Senão" do SQL

A instrução CASE é a sua ferramenta para criar lógicas condicionais dentro de uma query. Ela permite criar uma nova coluna baseada em regras. Por exemplo: "SE o preço for menor que 50, ENTÃO chame de 'Promoção', SENÃO, chame de 'Preço Normal'".

SELECT nome, preco, CASE WHEN preco < 50 THEN 'Promoção' ELSE 'Preço Normal' END AS categoria FROM produtos;
nomepreco
Caneta19.99
Teclado99.90
Mouse49.50

4. Window Functions: Análise Sequencial

As Funções de Janela são um superpoder do SQL. Elas realizam cálculos em um conjunto de linhas (uma "janela") relacionadas à linha atual. Diferente do GROUP BY que agrega tudo em uma única linha, as Window Functions retornam um valor para cada linha. São perfeitas para criar rankings, calcular médias móveis ou totais acumulados.

SELECT produto, vendas, RANK() OVER (ORDER BY vendas DESC) AS ranking FROM vendas_mensais;
produtovendas
Produto A9500
Produto B7200
Produto C9500
Produto D8100

5. CTEs: Organizando Queries Complexas

As Expressões de Tabela Comuns (CTEs), iniciadas com a cláusula WITH, são como criar uma tabela temporária e nomeada que existe apenas durante a execução da query. Elas são essenciais para quebrar consultas longas e complexas em blocos lógicos e legíveis, evitando subqueries aninhadas e confusas.

WITH VendasPorRegiao AS (
SELECT regiao, SUM(vendas) AS total_vendas
FROM filiais GROUP BY regiao
)
SELECT * FROM VendasPorRegiao WHERE total_vendas > 50000;

Tabela Original (filiais):

filial_idregiaovendas
1Sudeste30000
2Nordeste25000
3Sudeste40000
4Sul45000
5Nordeste35000

6. Subqueries: Uma Query Dentro de Outra

Uma Subquery (ou subconsulta) é uma instrução SELECT aninhada dentro de outra query. Ela é executada primeiro, e seu resultado é usado como filtro para a consulta principal. É uma alternativa poderosa às CTEs para resolver problemas em etapas, como: "Primeiro, encontre o ID da categoria 'Eletrônicos', depois, me mostre todos os produtos dessa categoria".

SELECT * FROM produtos WHERE id_categoria IN (
SELECT id FROM categorias WHERE nome = 'Eletrônicos'
);

Tabelas Originais:

produtos
idnomeid_categoria
10Teclado1
11Caneta2
12Mouse1
categorias
idnome
1Eletrônicos
2Papelaria

7. UNION: Combinando Listas

O operador UNION é usado para combinar o resultado de duas ou mais instruções SELECT em uma única lista. É como pegar duas listas de convidados e juntá-las em uma só, removendo automaticamente os nomes duplicados. É perfeito para consolidar dados de tabelas diferentes que possuem a mesma estrutura de colunas.

SELECT nome, email FROM clientes_ativos
UNION
SELECT nome, email FROM clientes_novos;

Tabelas Originais:

clientes_ativos
nomeemail
Anaana@email.com
Brunobruno@email.com
clientes_novos
nomeemail
Carloscarlos@email.com
Anaana@email.com

8. Self-Join: Relacionando uma Tabela com Ela Mesma

Um SELF JOIN é uma técnica onde você junta uma tabela com ela mesma, tratando-a como se fossem duas tabelas distintas (usando apelidos, como e para empregados e m para gerentes). É a solução perfeita para consultar dados hierárquicos, como encontrar o nome do gerente de cada funcionário.

SELECT e.nome AS funcionario, m.nome AS gerente
FROM funcionarios e JOIN funcionarios m ON e.id_gerente = m.id;

Tabela Original (funcionarios):

idnomeid_gerente
1CarlosNULL
2Ana1
3Bruno1

9. Funções de Data: Viajando no Tempo

Manipular datas é uma tarefa diária em análise de dados. Funções como NOW(), DATE(), e operadores de intervalo (INTERVAL) permitem filtrar registros em períodos específicos, como "todos os usuários que se cadastraram nos últimos 30 dias", uma query essencial para analisar o crescimento recente.

SELECT nome, data_cadastro FROM usuarios
WHERE data_cadastro >= NOW() - INTERVAL '30 day';

Tabela Original (usuarios):

nomedata_cadastro