Hier is een truc:het berekenen van een SUM()
van waarden waarvan bekend is dat ze 1 of 0 zijn, is gelijk aan een COUNT()
van de rijen waar de waarde 1 is. En u weet dat een booleaanse vergelijking 1 of 0 (of NULL) oplevert.
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;
Wat betreft de bonusvraag, je zou gewoon een inner join kunnen doen in plaats van een outer join, wat zou betekenen dat er alleen categorieën zijn met ten minste één rij in map
zou worden geretourneerd.
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;
Hier is een andere oplossing, die niet zo efficiënt is, maar ik zal het laten zien om uit te leggen waarom je de fout hebt gekregen:
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;
U kunt geen kolomaliassen gebruiken in de WHERE
clausule, omdat expressies in de WHERE
clausule worden geëvalueerd vóór de expressies in de selectielijst. Met andere woorden, de waarden die zijn gekoppeld aan selectielijstuitdrukkingen zijn nog niet beschikbaar.
U kunt kolomaliassen gebruiken in de GROUP BY
, HAVING
, en ORDER BY
clausules. Deze clausules worden uitgevoerd nadat alle uitdrukkingen in de selectielijst zijn geëvalueerd.