MySQL GROUP BY i HAVING klauzula s primjerima
โก Pametni saลพetak
SQL klauzule GROUP BY i HAVING pretvaraju detaljne retke u saลพeta izvjeลกฤa. GROUP BY saลพima retke koji dijele iste vrijednosti u jedan redak po grupi, dok HAVING filtrira te grupe nakon ลกto su primijenjene agregacijske funkcije poput COUNT.

ล to je SQL GROUP BY klauzula?
Klauzula GROUP BY je SQL naredba koja se koristi za grupirati retke koji imaju iste vrijednostiNapisuje se unutar SELECT naredbe i obiฤno se koristi zajedno s agregacijskim funkcijama za izradu saลพetih izvjeลกฤa iz baze podataka.
To je ono ลกto radi: to saลพima podatke pohranjenih u bazi podataka. Upiti koji sadrลพe klauzulu GROUP BY nazivaju se grupirani upiti i vraฤaju jedan redak za svaku grupiranu stavku.
SQL GROUP BY Sintaksa
Sada kada je svrha klauzule jasna, pogledajte sintaksu osnovnog grupiranog upita.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
OVDJE
- "SELECT naredbeโฆ"je standard" SQL SELECT upit naredbe.
- "GROUP BY naziv_stupca1" je klauzula koja izvrลกava grupuping na temelju naziva_stupca1.
- "[, naziv_stupca2, โฆ]โ je opcionalno i predstavlja nazive drugih stupaca kada je grupaping se vrลกi na viลกe od jednog stupca.
- "[STANJE IMA]โ je opcionalan i koristi se za ograniฤavanje redaka na koje utjeฤe klauzula GROUP BY. Sliฤan je WHERE klauzula, osim ลกto se nanosi nakon gruping.
Grouping Koriลกtenje jednog stupca
Najbrลพi naฤin da se vidi uฤinak SQL klauzule GROUP BY jest usporedba negrupiranog upita s grupiranim. Poฤnite s jednostavnim upitom koji vraฤa svaki unos spola u tablici ฤlanova.
SELECT `gender` FROM `members`;
| rod |
|---|
| ลพenski |
| ลพenski |
| Muลกki |
| ลพenski |
| Muลกki |
| Muลกki |
| Muลกki |
| Muลกki |
| Muลกki |
Vraฤa se devet redaka i svaka vrijednost se ponavlja. Pretpostavimo da umjesto toga ลพelimo jedinstvene vrijednosti za spol. Upit u nastavku dodaje klauzulu GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Izvrลกavanje gornje skripte u MySQL Radna tezga u odnosu na myflixdb daje nam sljedeฤe rezultate.
| rod |
|---|
| ลพenski |
| Muลกki |
Imajte na umu da su vraฤena samo dva retka jer tablica sadrลพi samo dva tipa spola. Klauzula GROUP BY grupirala je sve ฤlanove "Muลกki" i vratila jedan redak za njih, a isto je uฤinila i sa ฤlanovima "ลฝenski".
Grouping Koriลกtenje viลกe stupaca
Grouping na jednom stupcu je ฤesto pregrubo za pravo izvjeลกฤe. GROUP BY prihvaฤa popis stupaca odvojen zarezima, a kombinacija njihovih vrijednosti definira svaku grupu.
Pretpostavimo da ลพelimo popis vrijednosti category_id filma i odgovarajuฤe godine u kojima su filmovi objavljeni. Prvo promotrite izlaz ovog jednostavnog upita.
SELECT `category_id`, `year_released` FROM `movies`;
| kategorija_id | godina_izdana |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Istaknuti retci pokazuju da rezultat sadrลพi duplikate. Izvrลกavanje istog upita s GROUP BY ih uklanja.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Izvrลกavanje gornje skripte u MySQL Workbench u odnosu na myflixdb daje nam sljedeฤe rezultate prikazane u nastavku.
| kategorija_id | godina_izdana |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
Klauzula GROUP BY djeluje i na category_id i na year_released kako bi identificirala jedinstveni retci. Dva duplicirana retka za kategoriju 6 u 2007. godini su se spojila u jedan.
Pravilo palca: Ako je ID kategorije isti, ali je godina izdavanja drugaฤija, redak se tretira kao jedinstven. Ako su ID kategorije i godina izdavanja isti za viลกe redaka, retci su duplikati i prikazuje se samo jedan od njih.
Grouping i agregacijske funkcije
Uklanjanje duplikata je korisno, ali prava moฤ grupeping pojavljuje se kada je uparen s agregatne funkcijeAgregacijska funkcija izraฤunava jednu vrijednost za svaku grupu: COUNT broji retke, SUM zbraja vrijednosti i AVG, MIN i MAX opisuju rasprลกenost.
Pretpostavimo da ลพelimo ukupan broj muลกkih i ลพenskih ฤlanova u bazi podataka. Skript u nastavku to radi.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Izvrลกavanje gornje skripte u MySQL Workbench na myflixdb daje nam sljedeฤe rezultate.
| rod | COUNT(`broj_ฤlanstva`) |
|---|---|
| ลพenski | 3 |
| Muลกki | 6 |
Redci su grupirani prema svakoj jedinstvenoj vrijednosti spola, a broj redaka unutar svake grupe broji se pomoฤu agregacijske funkcije COUNT. Devet zapisa ฤlanova saลพima se u dva saลพeta retka.
Ograniฤavanje rezultata upita pomoฤu klauzule HAVING
Groupingnisu uvijek poลพeljni za svaki redak u tablici. Ponekad izvjeลกฤe mora biti ograniฤeno na zadani kriterij, a to je zadatak klauzule HAVING.
Pretpostavimo da ลพelimo znati sve godine izlaska za filmsku kategoriju s ID-om 8. Skript u nastavku postiลพe taj rezultat.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Izvrลกavanje gornje skripte u MySQL Workbench u odnosu na myflixdb daje nam sljedeฤe rezultate prikazane u nastavku.
| film_id | naslov | direktor | godina_izdana | kategorija_id |
|---|---|---|---|---|
| 9 | Honey moonERS | John Schultz | 2005 | 8 |
| 5 | Tatine djevojฤice | NULL | 2007 | 8 |
Samo filmovi s ID-om kategorije 8 zadrลพani su uvjetom HAVING.
Upozorenje: MySQL Verzija 5.7 i novije omoguฤuju naฤin rada ONLY_FULL_GROUP_BY prema zadanim postavkama, a u tom naฤinu rada SELECT * s klauzulom GROUP BY se odbija jer movie_id, title i director nisu ni grupirani ni agregirani. U produkciji, grupirane stupce eksplicitno imenujte, na primjer ODABERI category_id, year_leased FROM movies GROUP BY category_id, year_leased HAVING category_id = 8;
WHERE vs HAVING vs GROUP BY vs ORDER BY
Poฤetnici ฤesto mijeลกaju ove ฤetiri klauzule jer sve one oblikuju skup rezultata. Razlika leลพi u kada MySQL primjenjuje ih: WHERE se izvrลกava prije grupiranja redaka, HAVING se izvrลกava nakon toga, a ORDER BY se izvrลกava posljednji od svih.
| Klauzula | Ono ลกto se takoฤer | Kada se pokrene | Prihvaฤa agregacijske funkcije |
|---|---|---|---|
| GDJE | Filtrira pojedinaฤne retke prije bilo koje grupeping. | Prije GROUP BY | Ne |
| GROUP BY | Saลพima retke koji dijele iste vrijednosti u jedan redak po grupi. | Nakon GDJE | Nije primjenjivo |
| IMAJUฤI | Filtrira grupe koje je proizvela naredba GROUP BY. | Nakon GRUPIRA PO | Da, na primjer HAVING COUNT(*) > 2 |
| NARUฤITE PO | Sortira retke koji preลพivljavaju prethodne reฤenice. | Prezime | Da, agregirani alias se moลพe sortirati |
Praktiฤna posljedica je posljedica performansi. Filtriranje s WHERE uklanja retke prije grupeping rad poฤinje, pa uvjet koji ne ovisi o agregiranom rezultatu pripada u WHERE, a ne u HAVING.
