17 Grupeerimine ja gruppide piiramine

Grupeerimine

Vaatame, kuidas on võimalik agregeerivaid funktsioone kasutavate päringute tulemusi grupeerida, mida see üldse tähendab ning kuidas see meile kasulik on.

Eelmise peatükis katsetasime me järgnevat päringut:

  • SELECT nimi, AVG(rahvastikuarv) FROM riigid;

Päringu jooksutamisel nägime veateadet, kus mainiti märksõnapaari GROUP BY ning seda, et tunnus nimi peab sellega koos esinema. Jooksutame seega järgnevalt parandatud päringut:

  • SELECT nimi, AVG(rahvastikuarv) FROM riigid GROUP BY nimi;

Näeme, et selline “parandatud” päring töötab, kuid et see on võrdlemisi mõttetu, kuna selle tulemus on võrdne järgneva, lihtsama päringu tulemusega:

  • SELECT nimi, rahvastikuarv FROM riigid;

Kas GROUP BY kasutamine ning grupeerimine on seega mõttetu? Kindlasti mitte.

Põhjus, miks ülalolev märksõnu GROUP BY kasutav päring nii-öelda huvitav ei ole, on lihtne. Päringu jooksutamisel täidetakse esmalt GROUP BY osa ehk riike grupeeritakse tunnuse nimi alusel. See tähendab seda, et kõik sama nimega riigid pannakse ühte gruppi. Seejärel kuvatakse tulemuses iga grupi nimi ning gruppides olevate riikide keskmine rahvastikuarv. Kuna kõigil riikidel on erinevad nimed, on igas grupis vaid üks riik ning iga grupi keskmine rahvastikuarv ongi selle riigi rahvastikuarv.

Jooksutame nüüd järgnevat päringut:

  • SELECT LEFT(nimi, 1), AVG(rahvastikuarv) FROM riigid GROUP BY LEFT(nimi, 1);

Seekord saime juba palju huvitavama tulemuse. Nüüd grupeeriti riike nimede algustähtede alusel ning keskmised rahvastikuarvud arvutati nendesse gruppidesse kuuluvate riikide rahvastikuarvude põhjal.

Pane tähele, et kasutades päringulause SELECT osas mitteagregeerivaid avaldisi või funktsioone, nagu LEFT(nimi, 1) või ka lihtsalt nimi, peab see kindlasti esinema samal kujul ka GROUP BY osas. See ei kehti aga agregeerivate funktsioonide puhul, nagu eelnevas lauses kasutatud AVG(rahvastikuarv).

Kasutades grupeerimist võib SELECT osas olla mitteagregeerivaid avaldisi või funktsioone vabalt ka mitu, kuid samamoodi tuleb need kõik ka GROUP BY osas üles loetleda. See teadmine on ennekõike kasulik siis, kui luua päringuid mitme tabeli põhjal, mida vaatame järgmises peatükis.

Kuna grupeerimine on midagi täiesti uut ja pöörab seni õpitu kohati pea peale, on parim viis selle kasutama õppimiseks seda palju harjutada. Proovi ka ise koostada erinevaid huvitavaid päringuid kasutades märksõnu GROUP BY ja kombineeri seda kõige muu varem õpituga.

Gruppide piiramine

Siiani oleme me päringuid piiranud vaid märksõna WHERE abil. Ka õpitud grupeerimist kasutavaid päringuid saab edukalt piirata, kuid selleks tuleb lisaks märksõnale WHERE kasutada aeg-ajalt ka uut märksõna HAVING. Kuna kumba neist kasutada, vaatame peatselt.

Jooksuta järgnevat päringut:

  • SELECT naitleja_id, COUNT(*) FROM naitlemine GROUP BY naitleja_id HAVING COUNT(*) >= 25;

Näeme, et märksõna HAVING ja sellele järgnev osa käib seniõpitud päringustruktuuri lõppu, nii nagu WHERE käis tavapäraste päringute puhul.

Agregeeriva funktsiooni kasutamine koos mitteagregeerivate tunnuste, avaldiste, funktsioonide ja muu taolisega tähendab automaatselt seda, et on tarvis grupeerida. Seega saab agregeeriva funktsiooni väärtuse põhjal piiramiseks kasutada vaid märksõna HAVING. Mitteagregeerivate päringu osade põhjal piiramiseks saab kasutada nii märksõna WHERE kui ka märksõna HAVING. Esimene neist on enne ning teine pärast grupeerimist piiramiseks.

Seega, kui tahta eelnevat päringut piirata ka mitteagregeeriva tunnuse naitleja_id põhjal, saaks seda teha enne GROUP BY osa märksõnaga WHERE või pärast grupeerimist märksõnaga HAVING.

Tänu piirangu kasutamisele nägime eelneva päringu tulemuses vaid nende näitlejate ID-sid, kes on näidelnud 25-s või rohkemas Netflixis olevas teoses. Mõnes mõttes võib seda tõlgendada kui populaarsete (või ka töökate) näitlejate nimekirja.

Kui soovime ka teada saada, mis on nende populaarsete näitlejate nimed, peaksime (praeguste teadmiste kohaselt) nende ID-d meelde jätma ning neid seejärel tabelist Isikud otsima hakkama. Kuna tabelis Isikud tabelis on tuhandeid kirjed, on seda väga tüütu teha.

Õnneks on selle protsessi kiirendamiseks võimalik tabelite Data vaates kasutada filtreerimist, nii nagu alloleval pildil.

Tabeli andmete filtreerimine

Luues päringut mitme tabeli põhjal on päringulauset võimalik koostada ka nii, et selle tulemuses oleksidki koheselt nimed, mitte ID-d. Seda õpime juba järgmises peatükis.

Tasub teada, et üldjoontes töötab agregeeritud väärtuse piiramine vägagi sarnaselt tavapärasele piiramisele ning et see toetab kõiki varasemalt õpitud piiramise abimärksõnu.

Mõlemaid piiramiseks mõeldud märksõnu, WHERE ja HAVING, võib (ja sageli ka tuleb) kasutada ühes päringulauses erinevate tunnuste, avaldiste, funktsioonide jm alusel piiramiseks. Sealjuures tuleb hoolikalt valida, kumma märksõna abil midagi piiratakse.

Nüüd oleme õppinud kasutama grupeerimist agregeerivaid funktsioone kasutavates päringutes ning oskame ka loodud gruppe piirata. Seega saame õppida päringute tulemusi järjestama ning seda, kuidas päringuid mitme tabeli põhjal koostada.

 

Litsents

Icon for the Creative Commons Attribution 4.0 International License

Lisamoodulid on loodud Aveli Klaos, Siim Tanel Laisaar, Piret Luik, Tauno Palts, ja Eero Ääremaa poolt Creative Commons Attribution 4.0 International License litsentsi alusel, kui pole teisiti märgitud.

Jaga seda raamatut