sql >> Databáze >  >> RDS >> Mysql

Dotaz:počítejte více agregátů na položku

Zde je trik:výpočet SUM() hodnot, o kterých je známo, že jsou 1 nebo 0, je ekvivalentní COUNT() z řádků, kde je hodnota 1. A víte, že booleovské srovnání vrátí 1 nebo 0 (nebo 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;

Pokud jde o bonusovou otázku, můžete jednoduše provést vnitřní spojení místo vnějšího spojení, což by znamenalo pouze kategorie s alespoň jedním řádkem v map bude vráceno.

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;

Zde je další řešení, které není tak efektivní, ale ukážu ho, abych vysvětlil, proč došlo k chybě:

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;

V WHERE nelze použít aliasy sloupců klauzule, protože výrazy v WHERE klauzule jsou vyhodnoceny před výrazy ve výběrovém seznamu. Jinými slovy, hodnoty spojené s výrazy výběrového seznamu zatím nejsou dostupné.

V GROUP BY můžete použít aliasy sloupců , HAVING a ORDER BY doložky. Tyto klauzule se spustí poté, co byly vyhodnoceny všechny výrazy ve výběrovém seznamu.



  1. změnit výchozí formát data laravel sql dotaz

  2. scope_identity vs ident_current

  3. Převedení uživatelů z uživatelského jména na uživatelskou_skupinu

  4. mysql spojí dvě tabulky s ID oddělenými čárkami