Select max row group by, jak zjistit řádek s maximální hodnotou pro určitý příznak?

Tento článek popisuje techniku mysql dotazu, kterým získáme řádek s maximální hodnotou pro určitý příznak (sloupec). Určitě jsou i jiné způsoby, ale takhle to řeším já. Snad diskuse ukáže další přístupy.


Tento weblog je hlavně o praktických ukázkách, takže nejjednoduší bude ukázat na příkladu, který to řeší.

Obzvláště vhodné ukázky jsou různé tabulky statistik, např. web o kontinentální hokejové lize KHLpro a statistiky bodování jednotlivých týmů tabulky týmů. Kámen úrazu tkví v tom, že první příčky obsazují vítězové jednotlivých divizí.

Tudíž potřebujeme z tabulky vybrat týmy a řádky s jejich statistikami u těch, kteří v jednotlivých divizích mají maximální score, tedy prvním krokem bude GROUP BY divize.

Nebudu zdržovat a uvedu přímo, řešení.

  1. $q="SELECT t.*, ts.*
  2. FROM ".TB_TEAM_SCORE." as ts
  3. JOIN ".TB_TEAM." as t ON (t.IDteam=ts.IDteam)
  4. WHERE (IDdivision, season, score) IN
  5. (
  6. SELECT t.IDdivision, ts.season, max(score)
  7. FROM ".TB_TEAM_SCORE." as ts
  8. JOIN ".TB_TEAM." as t ON (t.IDteam=ts.IDteam)
  9. WHERE ts.season='".KHLpro::getActualSeason()."'
  10. GROUP BY t.IDdivision
  11. )
  12. ORDER BY score DESC
  13. LIMIT 4";

Snad není potřeba vysvětlovat jednotlivé konstanty a intuitivně se dopátráte jejich významu.

Analogicky samozřejmě dojdeme k nejmenší hodnotě apod.

Určitě je spousty dalších způsobů, např. tabulky joinovat. Pokud tedy v diskusi budou nějaké návrhy na další způsoby, rád je do tohoto článku přidám.

komentáře

RSS Komentáře k článku RSS Komentáře   Add to Google
19.03.2009 18:18 | Anonym (Jakub Vrána) | Více týmů se stejným score

Pokud má dotaz vybrat nejlepší týmy ze čtyř divizí, tak nebude fungovat správně, pokud budou mít dva týmy ve stejné divizi stejný počet bodů.

Je to rozebráno na http://php.vrana.cz/…hodnotou.php

20.03.2009 21:39 | Administrátor | Re: Více týmů se stejným score

ok, máš pravdu, potom snad ještě jednou group by

$q=„SELECT t., ts. FROM ".TB_TEAM_SCORE.“ as ts JOIN „.TB_TEAM.“ as t ON (t.IDteam=ts.ID­team) WHERE (IDdivision, season, score) IN
(
SELECT t.IDdivision, ts.season, max(score)
FROM „.TB_TEAM_SCORE.“ as ts
JOIN „.TB_TEAM.“ as t ON (t.IDteam=ts.ID­team)
WHERE ts.season=‚„.KHLpro::ge­tActualSeason()­.“‘
GROUP BY t.IDdivision
) GROUP BY t.IDdivision ORDER BY score DESC LIMIT 4";

z tvého článku jsem řešení nevyčetl, pokud tedy nepoložím 4 dotazy do dtb, ale samozřejmě více dotazů může být lepších než jeden složitý, ovšem jde tady spíš o princip, teď máme 4 divize, ale na jiném příkladu může být 1000 divizí (za diviz samozřejmě nahraď jiný příklad / příznak)

Jméno
Název
Text
Lze používat Texy! syntax. Příklad syntaxe: "text odkazu":odkaz, **tučně**, *kurzíva*, `code`. PHP kód uzavírejte do <?php ... ?> a JavaScript do <script> ... </script>