MySQL GROUP BY ja HAVING klausel koos näidetega
⚡ Nutikas kokkuvõte
SQL-laused GROUP BY ja HAVING muudavad detailsed read kokkuvõtvateks aruanneteks. GROUP BY koondab samade väärtustega read ühte ritta iga rühma kohta, samas kui HAVING filtreerib need rühmad pärast koondfunktsioonide (nt COUNT) rakendamist.

Mis on SQL-i GROUP BY-klausel?
Klausel GROUP BY on SQL-käsk, mida kasutatakse rühmita ridu, millel on samad väärtusedSee kirjutatakse SELECT-lause sees ja seda kasutatakse tavaliselt koos koondfunktsioonidega andmebaasist kokkuvõtlike aruannete loomiseks.
Seda see teebki: see võtab andmed kokku andmebaasis hoitakse. Päringuid, mis sisaldavad GROUP BY klauslit, nimetatakse rühmitatud päringuteks ja need tagastavad iga rühmitatud üksuse kohta ühe rea.
SQL GROUP BY Süntaks
Nüüd, kui klausli eesmärk on selge, vaadake lihtsa rühmitatud päringu süntaksit.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
SIIN
- "SELECT-laused…"on standard SQL SELECT käsupäring.
- "GROUP BY veeru_nimi1” on lause, mis täidab aluseping veeru_nimi1 põhjal.
- "[, veeru_nimi2, …]” on valikuline ja tähistab teisi veerunimesid, kui rühmping tehakse rohkem kui ühes veerus.
- "[OLEMASOLUKORD]” on valikuline ja seda kasutatakse GROUP BY klausli poolt mõjutatud ridade piiramiseks. See on sarnane lausega KUS klausel, välja arvatud see, et seda rakendatakse pärast kruntimistping.
Grouping Ühe veeru kasutamine
Kiireim viis SQL-i GROUP BY-klausli mõju nägemiseks on võrrelda rühmitamata päringut rühmitatud päringuga. Alustage lihtsa päringuga, mis tagastab kõik liikmete tabelis olevad sookirjed.
SELECT `gender` FROM `members`;
| sugu |
|---|
| Naine |
| Naine |
| Mees |
| Naine |
| Mees |
| Mees |
| Mees |
| Mees |
| Mees |
Tagastatakse üheksa rida ja iga väärtust korratakse. Oletame, et tahame hoopis soo unikaalseid väärtusi. Allolev päring lisab GROUP BY klausli.
SELECT `gender` FROM `members` GROUP BY `gender`;
Ülaltoodud skripti käivitamine MySQL Workbench myflixdb vastu annab meile järgmised tulemused.
| sugu |
|---|
| Naine |
| Mees |
Pane tähele, et tagastati ainult kaks rida, kuna tabel sisaldab ainult kahte sootüüpi. GROUP BY klausel grupeeris kõik „Mees” liikmed kokku ja tagastas nende jaoks ühe rea ning sama tegi ka „Nais” liikmetega.
Grouping Mitme veeru kasutamine
Grouping Ühe veeru puhul on see aruande jaoks sageli liiga umbkaudne. Funktsioon GROUP BY aktsepteerib komadega eraldatud veergude loendit ja iga rühma määratleb nende väärtuste kombinatsioon.
Oletame, et me tahame filmide kategooria_id väärtuste ja vastavate filmide ilmumisaastate loendit. Vaatleme kõigepealt selle lihtsa päringu väljundit.
SELECT `category_id`, `year_released` FROM `movies`;
| kategooria_id | aasta_välja antud |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Esiletõstetud read näitavad, et tulemus sisaldab duplikaate. Sama päringu käivitamine funktsiooniga GROUP BY eemaldab need.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Ülaltoodud skripti käivitamine MySQL Workbench myflixdb vastu annab meile järgmised tulemused, mis on näidatud allpool.
| kategooria_id | aasta_välja antud |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
GROUP BY klausel kasutab nii kategooria_id kui ka väljalaskeaasta (year_released) kriteeriume, et tuvastada ainulaadne read. 2007. aasta 6. kategooria kaks dubleerivat rida koondati üheks.
Pöidlareegel: Kui kategooria ID on sama, aga väljalaskeaasta on erinev, käsitletakse rida unikaalsena. Kui kategooria ID ja väljalaskeaasta on samad rohkem kui ühel real, on read duplikaadid ja kuvatakse ainult üks neist.
Grouping ja koondfunktsioonid
Duplikaatide eemaldamine on kasulik, aga grupi tegelik jõud peitubping ilmub, kui see on paaristatud koondfunktsioonidKoondfunktsioon arvutab iga rühma kohta ühe väärtuse: COUNT loendab ridu, SUM liidab väärtused ja AVG, MIN ja MAX kirjeldavad levikut.
Oletame, et tahame teada andmebaasis olevate mees- ja naisliikmete koguarvu. Allolev skript teeb seda.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Ülaltoodud skripti käivitamine MySQL Workbench myflixdb vastu annab meile järgmised tulemused.
| sugu | LOEND(`liikmete_number`) |
|---|---|
| Naine | 3 |
| Mees | 6 |
Read on rühmitatud iga unikaalse sooväärtuse järgi ja iga rühma sees olevate ridade arv loendatakse koondfunktsiooni COUNT abil. Üheksa liikmekirjet koondatakse kaheks kokkuvõtvaks reaks.
Päringutulemuste piiramine HAVING-klausli abil
Groupings-e ei ole alati vaja iga tabeli rea jaoks. Mõnikord tuleb aruannet piirata antud kriteeriumiga ja see on HAVING-klausli ülesanne.
Oletame, et tahame teada kõiki filmi kategooria ID 8 ilmumisaastaid. Allolev skript saavutab selle tulemuse.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Ülaltoodud skripti käivitamine MySQL Workbench myflixdb vastu annab meile järgmised tulemused, mis on näidatud allpool.
| filmi_id | pealkiri | juhataja | aasta_välja antud | kategooria_id |
|---|---|---|---|---|
| 9 | Honey moontv | John Schultz | 2005 | 8 |
| 5 | Isa väikesed tüdrukud | NULL | 2007 | 8 |
Tingimus HAVING säilitas ainult filmid kategooria ID-ga 8.
Hoiatus: MySQL 5.7 ja hilisemad versioonid lubavad vaikimisi režiimi ONLY_FULL_GROUP_BY ja selle režiimi korral lükatakse SELECT * koos GROUP BY klausliga tagasi, kuna filmi ID, pealkiri ja director ei ole grupeeritud ega koondatud. Tootmises nimetage grupeeritud veerud selgesõnaliselt, näiteks VALI kategooria_id, väljalaskeaasta FROM filmid GROUP BY kategooria_id, väljalaskeaasta OMADES kategooria_id = 8;
KUS vs OMANDAMINE vs GROUP BY vs ORDER BY
Algajad segavad neid nelja klauslit sageli, sest need kõik kujundavad tulemuste komplekti. Erinevus seisneb selles, et millal MySQL rakendab neid: WHERE käivitatakse enne ridade rühmitamist, HAVING pärast ja ORDER BY viimasena.
| Klausel | Mida see teeb | Kui see töötab | Aktsepteerib koondfunktsioone |
|---|---|---|---|
| KUS | Filtreerib üksikud read enne mis tahes rühmaping. | Enne GROUP BY | Ei |
| GROUP BY | Ahendab sama väärtusega read ühte ritta rühma kohta. | Pärast KUS | ei ole kohaldatav |
| VÕIMALIK | Filtreerib funktsiooni GROUP BY loodud rühmad. | Pärast GROUP BY | Jah, näiteks HAVING COUNT(*) > 2 |
| TELLI | Sorteerib read, mis jäävad ellu eelmiste klauslite järel. | viimane | Jah, koondaliast saab sortida |
Praktiline tagajärg on jõudlusega seotud. WHERE-filtreerimine eemaldab read enne groupiping töö algab, seega tingimus, mis ei sõltu koondtulemusest, kuulub pigem WHERE kui HAVING hulka.
