Du oplever samlet fanout i ovenstående forespørgsel.
Dette sker, fordi der er
- enten en 1-1 eller 1-N joinforbindelse mellem
aaa
&bbb
- der er en 1-N join mellem
bbb
&ccc
Sidstnævnte join opretter M
dubletter for rækker, der findes i bbb
hvis de er knyttet til M rækker via joinforbindelsen til ccc
For at rette fejlen skal du dele forespørgslen op i to CTE'er og slutte dig til resultatet.
WITH agg_bb AS (
SELECT aa.id, sum(bb.count)
FROM aaaa aa
LEFT JOIN bbbb bb ON bb.aa_id = aa.id
GROUP BY aa.id
)
, agg_cc AS (SELECT aa.id, count(DISTINCT cc.id)
FROM aaaa aa
LEFT JOIN bbbb bb ON bb.aa_id = aa.id
LEFT JOIN cccc cc ON cc.bb_id = bb.id
GROUP BY aa.id
)
SELECT * FROM agg_bb JOIN agg_cc USING (id)
For at undgå fan-outs skal du generelt kun anvende aggregerede operationer på kolonnerne fra relationen længst til højre i en serie af joinforbindelser. Hvis du opdager, at du samler kolonner fra de midterste tabeller, skal du dele forespørgslen op, som jeg har gjort ovenfor. Kun følgende funktioner er invariante på tværs af en fan-out:COUNT DISTINCT
, MIN
, MAX