Вот хитрость: вычисление 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
. Эти предложения выполняются после того, как все выражения в списке выбора были оценены.