Ve výše uvedeném dotazu dochází k souhrnnému rozvětvení.
To se děje, protože existuje
- buď spojení 1-1 nebo 1-N mezi
aaa
&bbb
- mezi
bbb
je spojení 1-N &ccc
Poslední spojení vytvoří M
duplikáty pro řádky, které existují v bbb
pokud jsou připojeny k M řádkům prostřednictvím spojení s ccc
Chcete-li chybu opravit, rozdělte dotaz na dva CTE a připojte výsledek.
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)
Obecně platí, že chcete-li se vyhnout rozvětvení, aplikujte agregační operace pouze na sloupce ze vztahu nejvíce vpravo v řadě spojení. Pokud zjistíte, že agregujete sloupce z prostředních tabulek, rozdělte dotaz tak, jak jsem to udělal výše. V rámci rozvětvení jsou neměnné pouze následující funkce:COUNT DISTINCT
, MIN
, MAX