Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Consulta:conte vários agregados por item


Aqui está um truque:calcular um SUM() de valores que são conhecidos como 1 ou 0 é equivalente a um COUNT() das linhas onde o valor é 1. E você sabe que uma comparação booleana retorna 1 ou 0 (ou 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;

Quanto à questão bônus, você poderia simplesmente fazer uma junção interna em vez de uma junção externa, o que significaria apenas categorias com pelo menos uma linha em map seria devolvido.
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;

Aqui está outra solução, que não é tão eficiente, mas vou mostrá-la para explicar por que você recebeu o erro:
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;

Você não pode usar aliases de coluna em WHERE cláusula, porque as expressões no WHERE cláusula são avaliadas antes das expressões na lista de seleção. Em outras palavras, os valores associados às expressões da lista de seleção ainda não estão disponíveis.

Você pode usar aliases de coluna no GROUP BY , HAVING e ORDER BY cláusulas. Essas cláusulas são executadas após todas as expressões na lista de seleção terem sido avaliadas.