Ето един трик:изчисляване на SUM()
от стойности, за които е известно, че са 1 или 0, е еквивалентен на COUNT()
от редовете, където стойността е 1. И знаете, че едно булево сравнение връща 1 или 0 (или 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;
Що се отнася до бонус въпроса, можете просто да направите вътрешно свързване вместо външно, което би означавало само категории с поне един ред в map
ще бъдат върнати.
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;
Ето друго решение, което не е толкова ефективно, но ще го покажа, за да обясня защо сте получили грешката:
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;
Не можете да използвате псевдоними на колони в WHERE
клауза, защото изрази в WHERE
клаузите се оценяват преди изразите в списъка за избор. С други думи, стойностите, свързани с изразите от списъка за избор, все още не са налични.
Можете да използвате псевдоними на колони в GROUP BY
, HAVING
и ORDER BY
клаузи. Тези клаузи се изпълняват, след като всички изрази в списъка за избор са оценени.