O que são Correlated Subqueries?

Uma Correlated Subquery (Subconsulta Correlacionada) é um tipo de subconsulta que depende de valores da consulta externa. Ao contrário das subconsultas normais, que podem ser executadas de forma independente da consulta principal, uma subconsulta correlacionada é executada repetidamente, uma vez para cada linha da consulta externa. Isso significa que a subconsulta está "correlacionada" com a linha atual da consulta externa, utilizando os valores dessa linha para produzir resultados.

Como Funcionam?

Em uma subconsulta correlacionada, a subconsulta faz referência a uma ou mais colunas da consulta externa. A execução da subconsulta ocorre para cada linha processada na consulta externa. Isso pode tornar as consultas correlacionadas mais lentas do que subconsultas independentes, especialmente em grandes conjuntos de dados, porque a subconsulta é avaliada múltiplas vezes.

Estrutura Básica

A estrutura de uma subconsulta correlacionada geralmente se parece com isto:

SELECT coluna1, coluna2, ...
FROM tabela_externa AS te
WHERE coluna = (
    SELECT alguma_coluna
    FROM tabela_interna AS ti
    WHERE te.coluna_correlacionada = ti.coluna_correlacionada
);

Aqui, te.coluna_correlacionada é a coluna da consulta externa usada dentro da subconsulta.

Exemplo 1: Encontrar o Salário Máximo por Departamento

Imagine uma tabela chamada Empregados com as colunas id_empregado, nome, salario, e id_departamento. Queremos encontrar os detalhes dos empregados que têm o salário máximo em seu respectivo departamento.

SELECT nome, salario, id_departamento
FROM Empregados e1
WHERE salario = (
    SELECT MAX(salario)
    FROM Empregados e2
    WHERE e1.id_departamento = e2.id_departamento
);

Explicação:

Exemplo 2: Encontrar Clientes com Pedidos Acima da Média

Suponha que temos uma tabela Clientes e uma tabela Pedidos. Queremos encontrar os clientes que fizeram pedidos cujo valor total está acima da média de todos os pedidos.

SELECT nome_cliente, id_cliente
FROM Clientes c
WHERE EXISTS (
    SELECT 1
    FROM Pedidos p
    WHERE p.id_cliente = c.id_cliente
    AND p.valor_total > (
        SELECT AVG(valor_total)
        FROM Pedidos
    )
);

Explicação: