Ecco un trucco:calcolare un SUM()
di valori noti per essere 1 o 0 equivale a un COUNT()
delle righe in cui il valore è 1. E sai che un confronto booleano restituisce 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;
Per quanto riguarda la domanda bonus, potresti semplicemente fare un inner join invece di un outer join, il che significherebbe solo categorie con almeno una riga in map
verrebbe restituito.
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;
Ecco un'altra soluzione, che non è così efficiente ma la mostrerò per spiegare perché hai ricevuto l'errore:
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;
Non puoi utilizzare alias di colonna in WHERE
clausola, perché le espressioni in WHERE
clausole vengono valutate prima delle espressioni nell'elenco di selezione. In altre parole, i valori associati alle espressioni dell'elenco di selezione non sono ancora disponibili.
Puoi utilizzare gli alias di colonna in GROUP BY
, HAVING
e ORDER BY
clausole. Queste clausole vengono eseguite dopo che tutte le espressioni nell'elenco di selezione sono state valutate.