Här är ett trick:beräkna en SUM()
av värden som är kända för att vara antingen 1 eller 0 motsvarar en COUNT()
av raderna där värdet är 1. Och du vet att en boolesk jämförelse returnerar 1 eller 0 (eller 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;
När det gäller bonusfrågan kan du helt enkelt göra en inre koppling istället för en yttre koppling, vilket skulle innebära endast kategorier med minst en rad i map
skulle returneras.
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;
Här är en annan lösning, som inte är lika effektiv men jag ska visa den för att förklara varför du fick felet:
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;
Du kan inte använda kolumnalias i WHERE
sats, eftersom uttryck i WHERE
satsen utvärderas före uttrycken i urvalslistan. Med andra ord, värdena som är associerade med vallistauttryck är inte tillgängliga ännu.
Du kan använda kolumnalias i GROUP BY
, HAVING
och ORDER BY
klausuler. Dessa satser körs efter att alla uttryck i urvalslistan har utvärderats.