MySQL GROUP BY ja HAVING-lauseke esimerkkeineen
โก รlykรคs yhteenveto
SQL-lausekkeet GROUP BY ja HAVING muuttavat yksityiskohtaiset rivit yhteenvetoraporteiksi. GROUP BY kutistaa samat arvot jakavat rivit yhdeksi riviksi ryhmรครค kohden, kun taas HAVING suodattaa kyseiset ryhmรคt koontifunktioiden, kuten COUNT, soveltamisen jรคlkeen.

Mikรค on SQL GROUP BY -lauseke?
GROUP BY -lause on SQL-komento, johon on totuttu ryhmittele rivit, joilla on samat arvotSe kirjoitetaan SELECT-lausekkeen sisรคlle, ja sitรค kรคytetรครคn yleensรค yhdessรค koostefunktioiden kanssa yhteenvetoraporttien luomiseen tietokannasta.
Sitรค se tekee: se tiivistรครค tiedot tietokannassa. GROUP BY -lauseen sisรคltรคviรค kyselyitรค kutsutaan ryhmitellyiksi kyselyiksi, ja ne palauttavat yhden rivin jokaista ryhmiteltyรค alkiota kohden.
SQL GROUP BY Syntaksi
Nyt kun lausekkeen tarkoitus on selvรค, tarkastellaan yksinkertaisen ryhmitellyn kyselyn syntaksia.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
TรรLTร
- "SELECT-lausekkeetโฆ"on standardi SQL SELECT komentokysely.
- "GROUP BY sarakkeen_nimi1โ on lauseke, joka suorittaa ryhmรคnping perustuu sarakkeen_nimi1:een.
- "[, sarakkeen_nimi2, โฆ]โ on valinnainen ja edustaa muita sarakenimiรค, kun ryhmรคping tehdรครคn useammalla kuin yhdellรค sarakkeella.
- "[ON ehto]โ on valinnainen ja sitรค kรคytetรครคn rajoittamaan GROUP BY -lausekkeen vaikutuspiiriin kuuluvia rivejรค. Se on samanlainen kuin WHERE-lauseke, paitsi ettรค sitรค kรคytetรครคn maanpinnan jรคlkeenping.
Grouping Yhden sarakkeen kรคyttรคminen
Nopein tapa nรคhdรค SQL GROUP BY -lauseen vaikutus on verrata ryhmittelemรคtรถntรค kyselyรค ryhmiteltyyn kyselyyn. Aloita yksinkertaisella kyselyllรค, joka palauttaa kaikki sukupuolimerkinnรคt jรคsentaulukossa.
SELECT `gender` FROM `members`;
| sukupuoli |
|---|
| Nainen |
| Nainen |
| Mies |
| Nainen |
| Mies |
| Mies |
| Mies |
| Mies |
| Mies |
Palautetaan yhdeksรคn riviรค ja jokainen arvo toistetaan. Oletetaan, ettรค haluamme sen sijaan sukupuolen yksilรถlliset arvot. Alla oleva kysely lisรครค GROUP BY -lauseen.
SELECT `gender` FROM `members` GROUP BY `gender`;
Suoritetaan yllรค oleva komentosarja MySQL Tyรถpรถytรค myflixdb:tรค vastaan โโantaa meille seuraavat tulokset.
| sukupuoli |
|---|
| Nainen |
| Mies |
Huomaa, ettรค palautettiin vain kaksi riviรค, koska taulukossa on vain kaksi sukupuolityyppiรค. GROUP BY -lauseke ryhmitteli kaikki "Mies"-jรคsenet yhteen ja palautti heille yhden rivin, ja se teki saman "Nais"-jรคsenten kanssa.
Grouping Useiden sarakkeiden kรคyttรคminen
Grouping Yhden sarakkeen funktio on usein liian karkea varsinaiseen raporttiin. GROUP BY hyvรคksyy pilkulla erotetun sarakeluettelon, ja niiden arvojen yhdistelmรค mรครคrittรครค kunkin ryhmรคn.
Oletetaan, ettรค haluamme listan elokuvien category_id-arvoista ja vastaavista julkaisuvuosista. Tarkastellaan ensin tรคmรคn yksinkertaisen kyselyn tulosta.
SELECT `category_id`, `year_released` FROM `movies`;
| kategorian_tunnus | vuosi_vapautettu |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Korostetut rivit osoittavat, ettรค tulos sisรคltรครค kaksoiskappaleita. Saman kyselyn suorittaminen GROUP BY -lausekkeella poistaa ne.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Suoritetaan yllรค oleva komentosarja MySQL Workbenchin vertailu myflixdb-tiedostoa vastaan โโantaa meille seuraavat tulokset.
| kategorian_tunnus | vuosi_vapautettu |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
GROUP BY -lauseke toimii sekรค category_id- ettรค year_released-tietojen perusteella tunnistaakseen unique rivit. Vuoden 2007 kategorian 6 kaksi pรครคllekkรคistรค riviรค yhdistettiin yhdeksi.
Nyrkkisรครคntรถ: Jos luokkatunnus on sama, mutta julkaisuvuosi on eri, riviรค kรคsitellรครคn yksilรถllisenรค. Jos luokkatunnus ja julkaisuvuosi ovat samat useammalla kuin yhdellรค rivillรค, rivit ovat kaksoiskappaleita ja vain toinen niistรค nรคytetรครคn.
Grouping ja aggregaattifunktiot
Kaksoiskappaleiden poistaminen on hyรถdyllistรค, mutta ryhmittelyn todellinen voimaping tulee nรคkyviin, kun se on yhdistetty kokonaisfunktiotKoostefunktio laskee yhden arvon kullekin ryhmรคlle: COUNT laskee rivit, SUMMA laskee arvot yhteen ja AVG, MIN ja MAX kuvaavat hajautusta.
Oletetaan, ettรค haluamme tietokannan mies- ja naisjรคsenten kokonaismรครคrรคn. Alla oleva skripti tekee sen.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Suoritetaan yllรค oleva komentosarja MySQL Workbenchin vertailu myflixdb-tiedostoa vastaan โโantaa seuraavat tulokset.
| sukupuoli | LASKU(`jรคsenyysnumero`) |
|---|---|
| Nainen | 3 |
| Mies | 6 |
Rivit ryhmitellรครคn jokaisen yksilรถllisen sukupuoliarvon mukaan, ja kunkin ryhmรคn sisรคllรค olevien rivien lukumรครคrรค lasketaan COUNT-koostefunktiolla. Yhdeksรคn jรคsentietuetta kutistetaan kahdeksi yhteenvetoriviksi.
Kyselytulosten rajoittaminen HAVING-lauseen avulla
Groupings-lausekkeita ei aina haluta jokaiselle taulukon riville. Joskus raportti on rajoitettava tiettyyn kriteeriin, ja se on HAVING-lauseen tehtรคvรค.
Oletetaan, ettรค haluamme tietรครค kaikki elokuvakategorian 8 julkaisuvuodet. Alla oleva skripti saavuttaa tรคmรคn tuloksen.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Suoritetaan yllรค oleva komentosarja MySQL Workbenchin vertailu myflixdb-tiedostoa vastaan โโantaa meille seuraavat tulokset.
| elokuvan_tunnus | otsikko | johtaja | vuosi_vapautettu | kategorian_tunnus |
|---|---|---|---|---|
| 9 | Honey mooners | John Schultz | 2005 | 8 |
| 5 | Isรคn pienet tytรถt | NULL | 2007 | 8 |
HAVING-ehto on sรคilyttรคnyt vain elokuvat, joiden kategoria-ID on 8.
Varoitus: MySQL 5.7 ja uudemmat versiot ottavat oletusarvoisesti kรคyttรถรถn ONLY_FULL_GROUP_BY-tilan, ja tรคssรค tilassa SELECT * GROUP BY -lausekkeella hylรคtรครคn, koska elokuvan_tunnusta, otsikkoa ja ohjaajaa ei ole ryhmitelty eikรค aggregoitu. Tuotannossa ryhmitellyt sarakkeet nimetรครคn eksplisiittisesti, esimerkiksi SELECT category_id, year_release FROM elokuvat GROUP BY category_id, year_release HAVING category_id = 8;
MISSร vs. OMISTAA vs. RYHMรLLร vs. LAJITTELUN MUKAAN
Aloittelijat sekoittavat usein nรคmรค neljรค lauseketta, koska ne kaikki muokkaavat tulosjoukkoa. Ero on siinรค, ettรค kun MySQL kรคyttรครค niitรค: WHERE suoritetaan ennen rivien ryhmittelyรค, HAVING sen jรคlkeen ja ORDER BY viimeisenรค.
| lauseke | Mitรค se tekee | Kun se toimii | Hyvรคksyy koostefunktiot |
|---|---|---|---|
| MISTร | Suodattaa yksittรคiset rivit ennen mitรค tahansa ryhmรครคping. | Ennen GROUP BY -toimintoa | Ei |
| GROUP BY | Kutistaa samat arvot jakavat rivit yhdeksi riviksi ryhmรครค kohden. | WHERE-sivun jรคlkeen | Ei sovellettavissa |
| oTTAA | Suodattaa GROUP BY -funktion tuottamat ryhmรคt. | GROUP BY -ohjelman jรคlkeen | Kyllรค, esimerkiksi HAVING COUNT(*) > 2 |
| TILAUS | Lajittelee rivit, jotka sรคilyvรคt edellisten lausekkeiden jรคlkeen. | Sukunimi | Kyllรค, koostealias voidaan lajitella |
Kรคytรคnnรถn seuraus on suorituskykyyn liittyvรค. WHERE-suodatus poistaa rivit ennen ryhmรครคnping tyรถ alkaa, joten ehto, joka ei ole riippuvainen koostetusta tuloksesta, kuuluu WHERE-luokkaan eikรค HAVING-luokkaan.
