Aquí hay un truco:calcular un SUM()
de valores que se sabe que son 1 o 0 es equivalente a un COUNT()
de las filas donde el valor es 1. Y sabe que una comparación booleana devuelve 1 o 0 (o 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;
En cuanto a la pregunta de bonificación, simplemente podría hacer una unión interna en lugar de una unión externa, lo que significaría solo categorías con al menos una fila en map
sería devuelto.
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;
Aquí hay otra solución, que no es tan eficiente pero la mostraré para explicar por qué obtuviste el error:
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;
No puede usar alias de columna en WHERE
cláusula, porque las expresiones en WHERE
se evalúan antes que las expresiones en la lista de selección. En otras palabras, los valores asociados con las expresiones de lista de selección aún no están disponibles.
Puede usar alias de columna en GROUP BY
, HAVING
y ORDER BY
cláusulas. Estas cláusulas se ejecutan después de que se hayan evaluado todas las expresiones de la lista de selección.