Zde je trik:výpočet SUM()
hodnot, o kterých je známo, že jsou 1 nebo 0, je ekvivalentní COUNT()
z řádků, kde je hodnota 1. A víte, že booleovské srovnání vrátí 1 nebo 0 (nebo NULL).
SELECT c.catname, COUNT(m.catid) AS item_count,
SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
LEFT JOIN map m USING (catid)
LEFT JOIN items i USING (itemid)
GROUP BY c.catid;
Pokud jde o bonusovou otázku, můžete jednoduše provést vnitřní spojení místo vnějšího spojení, což by znamenalo pouze kategorie s alespoň jedním řádkem v map
bude vráceno.
SELECT c.catname, COUNT(m.catid) AS item_count,
SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
INNER JOIN map m USING (catid)
INNER JOIN items i USING (itemid)
GROUP BY c.catid;
Zde je další řešení, které není tak efektivní, ale ukážu ho, abych vysvětlil, proč došlo k chybě:
SELECT c.catname, COUNT(m.catid) AS item_count,
SUM(i.ownerid = @ownerid) AS owner_item_count
FROM categories c
LEFT JOIN map m USING (catid)
LEFT JOIN items i USING (itemid)
GROUP BY c.catid
HAVING item_count > 0;
V WHERE
nelze použít aliasy sloupců klauzule, protože výrazy v WHERE
klauzule jsou vyhodnoceny před výrazy ve výběrovém seznamu. Jinými slovy, hodnoty spojené s výrazy výběrového seznamu zatím nejsou dostupné.
V GROUP BY
můžete použít aliasy sloupců , HAVING
a ORDER BY
doložky. Tyto klauzule se spustí poté, co byly vyhodnoceny všechny výrazy ve výběrovém seznamu.