Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Abfrage:Mehrere Aggregate pro Element zählen

Hier ist ein Trick:Berechnen einer SUM() von Werten, von denen bekannt ist, dass sie entweder 1 oder 0 sind, entspricht einem COUNT() der Zeilen, in denen der Wert 1 ist. Und Sie wissen, dass ein boolescher Vergleich 1 oder 0 (oder NULL) zurückgibt.

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;

Was die Bonusfrage betrifft, könnten Sie einfach einen inneren Join anstelle eines äußeren Joins machen, was bedeuten würde, dass nur Kategorien mit mindestens einer Zeile in map vorhanden sind zurückgegeben werden.

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;

Hier ist eine andere Lösung, die nicht so effizient ist, aber ich werde sie zeigen, um zu erklären, warum Sie den Fehler erhalten haben:

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;

Sie können keine Spaltenaliase im WHERE verwenden -Klausel, weil Ausdrücke in WHERE -Klausel werden vor den Ausdrücken in der Auswahlliste ausgewertet. Mit anderen Worten, die mit Auswahllistenausdrücken verknüpften Werte sind noch nicht verfügbar.

Sie können Spaltenaliase in GROUP BY verwenden , HAVING , und ORDER BY Klauseln. Diese Klauseln werden ausgeführt, nachdem alle Ausdrücke in der Auswahlliste ausgewertet wurden.