sql >> Database >  >> RDS >> Mysql

Query:tel meerdere aggregaten per item

Hier is een truc:het berekenen van een SUM() van waarden waarvan bekend is dat ze 1 of 0 zijn, is gelijk aan een COUNT() van de rijen waar de waarde 1 is. En u weet dat een booleaanse vergelijking 1 of 0 (of NULL) oplevert.

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;

Wat betreft de bonusvraag, je zou gewoon een inner join kunnen doen in plaats van een outer join, wat zou betekenen dat er alleen categorieën zijn met ten minste één rij in map zou worden geretourneerd.

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 is een andere oplossing, die niet zo efficiënt is, maar ik zal het laten zien om uit te leggen waarom je de fout hebt gekregen:

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;

U kunt geen kolomaliassen gebruiken in de WHERE clausule, omdat expressies in de WHERE clausule worden geëvalueerd vóór de expressies in de selectielijst. Met andere woorden, de waarden die zijn gekoppeld aan selectielijstuitdrukkingen zijn nog niet beschikbaar.

U kunt kolomaliassen gebruiken in de GROUP BY , HAVING , en ORDER BY clausules. Deze clausules worden uitgevoerd nadat alle uitdrukkingen in de selectielijst zijn geëvalueerd.



  1. Een meer dynamische manier om categorieën op meerdere niveaus te nesten

  2. Hoe een ADDM-taak te maken en het rapport ervan te controleren

  3. JDBC-verbindingen in pool sluiten

  4. Bulksgewijs invoegen in mySql en node.js met mysljs