Por que um JOIN duplica linhas e como corrigir a cardinalidade
Um JOIN combina linhas dos dois lados. Quando um cliente tem muitos pedidos, um JOIN simples retorna uma linha por pedido, então o cliente aparece várias vezes e qualquer total por cliente fica errado.
A resposta rápida
Defina a granularidade desejada, isto é, o que cada linha deve representar. Para obter um total por cliente, agregue o lado de muitos com SUM e agrupe pelo cliente, em vez de esconder duplicatas com DISTINCT.
Um exemplo mínimo
SELECT a.id, a.name, b.title
FROM authors a
JOIN books b ON b.author_id = a.id;SELECT a.id, a.name, COUNT(b.id) AS book_count
FROM authors a
JOIN books b ON b.author_id = a.id
GROUP BY a.id, a.name;A consulta com bug retorna uma linha para cada pedido; por isso, um cliente com dois pedidos aparece duas vezes. Agrupar por cliente e somar os pedidos produz uma linha correta para cada cliente.
Como depurar
- Declare a granularidade esperada: uma linha por cliente, por pedido ou por dia.
- Conte as linhas de cada lado do JOIN para uma chave conhecida.
- Se o resultado tem mais linhas que a granularidade pretendida, o JOIN está multiplicando linhas.
- Agregue o lado de muitos na granularidade pretendida em vez de mascarar linhas com DISTINCT.
Correções erradas comuns
- Adicionar DISTINCT, que esconde duplicatas mas não soma nada e pode descartar linhas legitimamente iguais.
- Usar LIMIT para fazer a contagem de linhas parecer certa sem corrigir o grão.
- Fazer o JOIN por uma chave incompleta, de modo que algumas linhas casam por acaso.
Limites deste guia
Isto cobre o espalhamento um-para-muitos para um total por cliente. Bugs de cardinalidade também aparecem com joins muitos-para-muitos e predicados ausentes. O desafio foca no caso de espalhamento mostrado aqui.
Referências oficiais
Pronto para experimentar?
Corrigir este bug em um desafio grátisPáginas relacionadas
O bug do await ausente em funções async do JavaScript
Um await ausente faz o JavaScript ler uma Promise como se fosse o valor resolvido. Veja a falha, a correção de uma linha e as correções erradas a evitar.
Por que um argumento padrão mutável vaza estado em Python
Uma lista usada como argumento padrão em Python é criada uma vez e compartilhada entre chamadas. Veja por que o estado vaza e a correção com guarda None.
Guias
Guias curtos de depuração que explicam um bug comum, mostram uma correção mínima e abrem um desafio grátis correspondente. Navegue pelos guias por linguagem.