1
resposta

Resolução Exercício - Filtrando empréstimos com pagamentos acima de R$ 1.000

WITH TotalPagamentoPorEmprestimo AS (
    SELECT
        p.id_emprestimo AS  id_emprestimo
    ,	SUM(p.Valor) AS total_pago_emprestimo
    FROM tabelapagamentos AS p
    GROUP BY
        p.id_emprestimo
),
EmprestimosSuperioresAMilReais AS (
    SELECT
        tp.id_emprestimo
    ,	tp.total_pago_emprestimo
    FROM TotalPagamentoPorEmprestimo AS tp
    WHERE total_pago_emprestimo >= 1000
)

SELECT
    id_emprestimo
,	total_pago_emprestimo
FROM EmprestimosSuperioresAMilReais
;

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

1 resposta

Olá, Carlos. Como vai?

Excelente entrega! Mais um código impecável que demonstra o seu domínio em criar fluxos lógicos e estruturados utilizando Common Table Expressions (CTEs) encadeadas.

O seu script cumpre perfeitamente o papel proposto. Ao criar a primeira CTE (TotalPagamentoPorEmprestimo), você agrupou e consolidou a soma dos pagamentos. Na segunda (EmprestimosSuperioresAMilReais), aplicou a regra de corte de negócio (>= 1000) de forma isolada. O resultado no Result Grid (empréstimos E02 com 1000 e E04 com 1200) valida a precisão da sua query.

Como você atua como Tech Lead e Engenheiro de Dados, quero trazer uma reflexão técnica refinada sobre plano de execução e otimização de consultas envolvendo agregados e filtros. Ela pode servir como um ótimo tópico de discussão ou mentoria para o time!


Análise de Performance: Duas CTEs vs. Cláusula HAVING

A estrutura encadeada que você usou funciona muito bem, é modular e extremamente legível. No entanto, em termos de processamento de banco de dados (especialmente se estivéssemos lidando com tabelas de pagamentos massivas com milhões de linhas), o mesmo resultado pode ser alcançado eliminando a necessidade de criar a segunda CTE.

Para fazer isso, basta aplicar o filtro do valor agregado diretamente na primeira CTE utilizando a cláusula HAVING.

Veja o comparativo estrutural de como a query ficaria mais enxuta:

WITH TotalPagamentoPorEmprestimo AS (
    SELECT
        p.id_emprestimo AS id_emprestimo,
        SUM(p.Valor) AS total_pago_emprestimo
    FROM tabelapagamentos AS p
    GROUP BY p.id_emprestimo
    -- O banco calcula a soma e já descarta o que é menor que 1000 em uma única etapa
    HAVING SUM(p.Valor) >= 1000
)
SELECT
    id_emprestimo,
    total_pago_emprestimo
FROM TotalPagamentoPorEmprestimo;

O impacto técnico dessa mudança:

  1. Simplificação do Plano de Execução: Na sua abordagem original, o otimizador do banco de dados gera uma tabela temporária lógica com todos os empréstimos somados para, em um segundo momento (na segunda CTE), ler essa tabela sequencialmente aplicando o WHERE. Com o HAVING, o descarte dos dados que não atingiram R$ 1.000 acontece durante a fase de agrupamento, reduzindo a quantidade de registros que sobem para a memória antes do SELECT final.
  2. Manutenibilidade: Menos linhas de código significam menos aliases para gerenciar (tp.id_emprestimo, etc.), reduzindo a complexidade visual do script para os desenvolvedores que forem ler a query no futuro.

A sua solução atual está ótima e o resultado analítico está corretíssimo. Trazer alternativas de modelagem como o uso do HAVING é o tipo de refinamento que otimiza custos de processamento em datalakes e armazéns de dados em produção.

Parabéns por mais uma bela contribuição no fórum!

Espero que possa ter lhe ajudado!