databázy (1) - predná ka 05 · podmienenévýrazy case–príklad select films.id, case when year...
TRANSCRIPT
Databázy (1)Prednáška 05
Alexander Š[email protected]
Contents I
Podmienené výrazy
Agregovanie dát
Viac zoskupovaní naraz
Podmienené výrazy
Section 1
Podmienené výrazy
Podmienené výrazy
Podmienené výrazy
Výrazy, ktorých hodnota závisí od podmienky
Podmienené výrazy
CASE – Variant testujúci podmienky
CASE WHEN podmienka_1 THEN výsledok_1[WHEN podmienka_2 THEN výsledok_2]...[WHEN podmienka_n THEN výsledok_n][ELSE výsledok_else]
END
Hodnotou celého výrazu je:I výraz výsledok_i prvej vetvy i, ktorej podmienka_i sa vyhodnotí na
TRUEI ináč je výsledkom výraz výsledok_else – ak else vetva nie je, potom
NULL
Podmienené výrazy
CASE – Príklad
SELECT films.id,CASE WHEN year < 1960 THEN ’archaic’
WHEN year BETWEEN 1960 AND 2000 THEN ’old’ELSE ’recent’
END AS commentFROM films
Podmienené výrazy
CASE – Variant porovnávajúci výraz
CASE výraz_0WHEN výraz_1 THEN výsledok_1[WHEN výraz_2 THEN výsledok_2]...[WHEN výraz_n THEN výsledok_n][ELSE výsledok_else]
END
Hodnotou celého výrazu je:I výraz výsledok_i prvej vetvy i, pre ktorú sa porovnanie
výraz_i = výraz_0 vyhodnotí na TRUEI ináč je výsledkom výraz výsledok_else – ak else vetva nie je, potom
NULL
Podmienené výrazy
CASE – Príklad
Cenu 0 nahradíme textom ’free’.
SELECT name,CASE price
WHEN 0 THEN ’free’ELSE price::VARCHAR
ENDFROM films
Keďže takto zmiešame čísla a text dokopy, musíme ostatné číslakonvertovať na text.
Podmienené výrazy
Pretypovanie
hodnota::typ
CAST (hodnota AS typ)
Podmienené výrazy
COALESCE
COALESCE(hodnota_1, [, ..., hodnota_n])
I vráti prvú neNULLovú hodnotuI ak sú všetky honoty NULL, potom vráti NULL
Podmienené výrazy
COALESCE – Príklad
SELECT user_name,COALESCE(countries.name, ’No country’) as country_name
FROM usersLEFT JOIN countries ON users.country_id = countries.id
Podmienené výrazy
NULLIF
NULLIF(hodnota_1, hodnota_2)
I ak sa hodnoty rovnajú, vráti NULLI ináč vráti hodnota_1
Podmienené výrazy
NULLIF – Príklad
SELECT user_name,NULLIF(countries.name, ’No country’) as country_name
FROM ...
Agregovanie dát
Section 2
Agregovanie dát
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Motivácia
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 12 4
Chceme zistiť koľko filmov ohodnotil používateľ s id 1.
count3
Agregovanie dát Agregačné funkcie
Agregačné funkcie
I syntax: nazov_funkcie(argument_1, ..., argument_n)I argumenty sa nevyhodnocujú pred volaním funkcie alebo počas jej
vyhodnocovaniaI implicitný argument – kolekcia riadkovI redukuje kolekciu na jednu hodnotu
Agregovanie dát Agregačné funkcie
Agregačné funkcie – count
count(*)I vráti počet riadkovI * je súčasťou (čudnej) syntaxe, nie je to reálny argument
count(výraz)I vráti počet riadkov, pre ktoré sa výraz vyhodnotí na neNULLovú
hodnotu
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Poradie vykonávania
Ak SELECT obsahuje agregačnú funkciu, vyhodnotenie sa zmení na:
1. vykonajú sa JOINy2. vyberú sa riadky spĺňajúce WHERE podmienku3. zatiaľ máme vo všeobecnosti tabuľku s veľa riadkami4. vyhodnotia sa všetky výrazy s agregačnými funkciami, čím dostaneme
jeden riadok; tabuľka z kroku 3 je implicitným argumentov agr. funkcie5. idú ďalšie fázy (rekapitulácia bude neskôr)
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad
Chceme zistiť koľko filmov ohodnotil používateľ s id 1.
SELECT count(*)FROM ratingsWHERE user_id = 1
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad
Chceme zistiť koľko filmov ohodnotil používateľ s id 1.
SELECT count(*)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad
Chceme zistiť koľko filmov ohodnotil používateľ s id 1.
SELECT count(*)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad
Chceme zistiť koľko filmov ohodnotil používateľ s id 1.
SELECT count(*)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 8
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad
Chceme zistiť koľko filmov ohodnotil používateľ s id 1.
SELECT count(*)FROM ratingsWHERE user_id = 1
count3
Agregovanie dát Agregačné funkcie
Agregačné funkcie sum, avg, max, min
sum(výraz)I vyhodnotí výraz pre každý riadok a získané hodnoty sčíta
avg(výraz)I vyhodnotí výraz pre každý riadok a zo získaných hodnôt spraví
aritmentický priemer
max(výraz)I vyhodnotí výraz pre každý riadok a zo získaných hodnôt vezme
maximum
min(výraz)I vyhodnotí výraz pre každý riadok a zo získaných hodnôt vezme
minimum
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 2
SELECT avg(rating), count(*)FROM ratingsWHERE user_id = 1
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 2
SELECT avg(rating), count(*)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 2
SELECT avg(rating), count(*)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 2
SELECT avg(rating), count(*)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 8
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 2
SELECT avg(rating), count(*)FROM ratingsWHERE user_id = 1
avg count6.67 3
Agregovanie dát Agregačné funkcie
Agregačné funkcie – bool_and, bool_or
bool_and(výraz)I vyhodnotí výraz pre každý riadokI vráti true ak všetky hodnoty sú true, ináč falseI nikdy nevráti NULL
bool_or(výraz)I vyhodnotí výraz pre každý riadokI vráti true ak aspoň jedna hodnota je true, ináč falseI nikdy nevráti NULL
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 3
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 12 4
Chceme zistiť, či používateľ 1 hodnotil nejaký film hodnotením 7
SELECT bool_or(rating == 7)FROM ratingsWHERE user_id = 1
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 3
Chceme zistiť, či používateľ 1 hodnotil nejaký film hodnotením 7
SELECT bool_or(rating == 7)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 3
Chceme zistiť, či používateľ 1 hodnotil nejaký film hodnotením 7
SELECT bool_or(rating == 7)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 3
Chceme zistiť, či používateľ 1 hodnotil nejaký film hodnotením 7
SELECT bool_or(rating == 7)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 8
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 3
Chceme zistiť, či používateľ 1 hodnotil nejaký film hodnotením 7
SELECT bool_or(rating == 7)FROM ratingsWHERE user_id = 1
user_id film_id rating1 1 101 6 21 7 8
rating == 7falsefalsetrue
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 3
Chceme zistiť, či používateľ 1 hodnotil nejaký film hodnotením 7
SELECT bool_or(rating == 7)FROM ratingsWHERE user_id = 1
bool_ortrue
Agregovanie dát Agregačné funkcie
Ak použijeme agregačnú funkciu, všetky SELECT výrazymusia agregovať riadky na jednu hodnotu
SELECT user_id, count(*)FROM ratings
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát Agregačné funkcie
Ak použijeme agregačnú funkciu, všetky SELECT výrazymusia agregovať riadky na jednu hodnotu
SELECT user_id, count(*)FROM ratings
user_id count1 2 5
Stĺpec user_id je typu číslo, nie pole čísel. Nevieme, ktorú z hodnôt sivybrať.
Agregovanie dát Agregačné funkcie
Nie každý výraz s agregačnou funkciou agreguje riadky najednu hodnotu
ratingsuser_id film_id rating
1 1 101 6 21 7 8
count(*) + 2 pre celú tabuľku vráti jednu hodnotucount(*) + film_id kvôli film_id dáva pre každý riadok inú hodnotu
Agregovanie dát Agregačné funkcie
Agregačné funkcie a NULLy
I count(*) započítava všetky riadky (aj s NULL hodnotami),I ostatné uvedené funkcie ignorujú NULLy
Agregovanie dát Agregačné funkcie
Agregačné funkcie a NULLy – Príklad
usersid name country_id1 fan123 12 johnny 43 stellar NULL
SELECT count(*), count(country_id)FROM users
count count3 2
Agregovanie dát Agregačné funkcie
Agregačné funkcie a žiadne riadky
Čo ak po aplikovaní WHERE podmienky neostane žiaden riadok?I count – vráti 0,I ostatné uvedené funkcie – vrátia NULL
Agregovanie dát Agregačné funkcie
Agregačné funkcie a duplicitné hodnoty
I agregačná_funkcia(výraz) – berie do úvahy duplicityI agregačná_funkcia(ALL výraz) – berie do úvahy duplicityI agregačná_funkcia(DISTINCT výraz) – duplicity ignoruje
Agregovanie dát Agregačné funkcie
Agregačné funkcie – Príklad 4
ratingsuser_id film_id rating
1 1 101 6 22 1 9
Chceme vypočítať počet hodnotení v priemere na jeden film.
SELECT count(film_id), count(DISTINCT film_id),count(film_id)::numeric/count(DISTINCT film_id)AS ratings_per_film
FROM ratings
count count ratings_per_film3 2 1.5
Agregovanie dát Agregačné funkcie
Agregovanie iba niektorých riadkov
Ak všetky agregované hodnoty majú byť z rovnakých riadkov, môžemepoužiť WHERE podmienku na výber riadkov.
Počet hodnotení > 5 a priemerné hodnotenie z hodnotení > 5
SELECT count(*), avg(rating)FROM ratingsWHERE rating > 5
Agregovanie dát Agregačné funkcie
Agregovanie iba niektorých riadkov
Ak agregované hodnoty majú byť nad rôznymi riadkami, musíme použiťFILTER
Počet hodnotení > 5 a priemerné hodnotenie z hodnotení <= 5
Agregovanie dát Agregačné funkcie
FILTER
názov_agregačnej_funkcie(parametre)FILTER (WHERE podmienka)
I do aplikovania agregačnej funkcie sa dostanú len riadky, pre ktoré sapodmienka vyhodnotí na TRUE
I podmienka môže referencovať aj iné stĺpce než tie, čo sú parametramiagregačnej funkcie
Agregovanie dát Agregačné funkcie
Agregovanie iba niektorých riadkov
Počet hodnotení > 5 a priemerné hodnotenie <= 5
SELECT count(*) FILTER (WHERE rating > 5),avg(rating) FILTER (WHERE rating <= 5)
FROM ratings
Agregovanie dát Agregačné funkcie
Agregovanie iba niektorých riadkov – Podmienené výrazy
SELECT count(CASEWHEN rating > 5 THEN 1ELSE NULL
END),avg(CASE
WHEN rating <= 5 THEN ratingELSE NULL
END)FROM ratings
Agregovanie dát GROUP BY
GROUP BY
Ak nechcem agregovať celú tabuľku ale po skupinách, použijeme klauzulu
GROUP BY goup_by_výraz_1, ..., group_by_výraz_n
Píše sa medzi WHERE a ORDER BY
Agregovanie dát GROUP BY
GROUP BY
GROUP BY goup_by_výraz_1, ..., group_by_výraz_n
Ako to funguje:I vyhodnotia sa joinyI aplikuje sa WHERE podmienkaI riadky sa rozdelia do skupín podľa výrazov group_by_výraz_1, ...,
group_by_výraz_nI na každú skupinu sa aplikujú agregačné funkcieI každá skupina v pôvodnej tabuľke sa stane riadkom v novej tabuľke
Agregovanie dát GROUP BY
GROUP BY – Príklad
SELECT user_id, count(*)FROM ratingsGROUP BY user_id
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát GROUP BY
GROUP BY – Príklad
SELECT user_id, count(*)FROM ratingsGROUP BY user_id
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát GROUP BY
GROUP BY – Príklad
SELECT user_id, count(*)FROM ratingsGROUP BY user_id
user_id film_id rating1 1 101 6 21 7 82 2 92 12 4
Agregovanie dát GROUP BY
GROUP BY – Príklad
SELECT user_id, count(*)FROM ratingsGROUP BY user_id
user_id count1 32 2
Agregovanie dát GROUP BY
GROUP BY – Príklad 2
Koľko používateľov hodnotilo daným hodnotením daný film
SELECT film_id, rating, count(*)FROM ratingsGROUP BY film_id, rating
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 6 23 7 83 6 8
Agregovanie dát GROUP BY
GROUP BY – Príklad 2
Koľko používateľov hodnotilo daným hodnotením daný film
SELECT film_id, rating, count(*)FROM ratingsGROUP BY film_id, rating
user_id film_id rating1 1 102 2 91 6 22 6 23 6 81 7 83 7 8
Agregovanie dát GROUP BY
GROUP BY – Príklad 2
Koľko používateľov hodnotilo daným hodnotením daný film
SELECT film_id, rating, count(*)FROM ratingsGROUP BY film_id, rating
film_id rating count1 10 12 9 16 2 26 8 17 8 2
Agregovanie dát GROUP BY
GROUP BY – Výrazy povolené v SELECT časti
SELECT zoznam_select_výrazov...GROUP BY group_by_výraz_1, ..., group_by_výraz_n
V zozname_select_výrazov môže byť iba:I výraz uvedený v GROUP BY častiI výraz agregujúci riadky na jednu hodnotu
Agregovanie dát GROUP BY
GROUP BY – Príklad 3
Počet filmov s hodnotením pod 5 a aspoň 5.
SELECT rating < 5, count(*)FROM ratingsGROUP BY rating < 5
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 6 23 7 43 6 8
Agregovanie dát GROUP BY
GROUP BY – Príklad 3
Počet filmov s hodnotením pod 5 a počet filmov s hodnotením aspoň 5.
SELECT rating < 5, count(*)FROM ratingsGROUP BY rating < 5
user_id film_id rating1 6 22 6 23 7 43 6 81 7 82 2 91 1 10
Agregovanie dát GROUP BY
GROUP BY – Príklad 3
Počet filmov s hodnotením pod 5 a počet filmov s hodnotením aspoň 5.
SELECT rating < 5, count(*)FROM ratingsGROUP BY rating < 5
?column? counttrue 3false 4
Agregovanie dát GROUP BY
V GROUP BY časti môžeme použiť aj alias stĺpca
SELECT rating < 5 AS under, count(*)FROM ratingsGROUP BY under
under counttrue 3false 4
Agregovanie dát GROUP BY
NULLy sú pre GROUP BY rovnaké – sú v jednej skupine
filmsid name year price3 Ubreakable 2000 82 Django Unchained 2012 104 Seven Samurai 1954 NULL6 Bram Stocker’s Dracula 1992 NULL1 Léon: The Professional 1994 NULL
SELECT price, count(*)FROM filmsGROUP BY price
price count8 110 1
NULL 3
Agregovanie dát GROUP BY
Poradie vykonávania
1. vykonajú sa JOINy2. vyberú sa riadky spĺňajúce WHERE podmienku3. riadky sa rozdelia do skupín podľa GROUP BY4. aplikujú sa agregačné funkcie, čím dostaneme jeden riadok pre každú
skupinu5. ...
Tým pádom nemôžeme agregačné funkcie použiť vo WHERE časti
Agregovanie dát HAVING
HAVING
HAVING booleovský_výraz
I HAVING klauzula sa píše za GROUP BY a pred ORDER BYI vyberá riadky po aplikovaní agregačnej funkcie
Agregovanie dát HAVING
HAVING – Príklad
Chceme filmy s aspoň dvomi hodnoteniami.
SELECT film_idFROM ratingsGROUP BY film_idHAVING count(*) >= 2
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 6 23 7 83 6 8
Agregovanie dát HAVING
HAVING – Príklad
Chceme filmy s aspoň dvomi hodnoteniami.
SELECT film_idFROM ratingsGROUP BY film_idHAVING count(*) >= 2
user_id film_id rating1 1 102 2 91 6 22 6 23 6 81 7 83 7 8
Agregovanie dát HAVING
HAVING – Príklad
Chceme filmy s aspoň dvomi hodnoteniami.
SELECT film_idFROM ratingsGROUP BY film_idHAVING count(*) >= 2
film_id count1 12 16 37 2
Agregovanie dát HAVING
HAVING – Príklad
Chceme filmy s aspoň dvomi hodnoteniami.
SELECT film_idFROM ratingsGROUP BY film_idHAVING count(*) >= 2
film_id count1 12 16 37 2
Agregovanie dát HAVING
HAVING – Príklad
Chceme filmy s aspoň dvomi hodnoteniami.
SELECT film_idFROM ratingsGROUP BY film_idHAVING count(*) >= 2
film_id count6 37 2
Agregovanie dát HAVING
HAVING – Príklad
Chceme filmy s aspoň dvomi hodnoteniami.
SELECT film_idFROM ratingsGROUP BY film_idHAVING count(*) >= 2
film_id67
Agregovanie dát Agregovanie a primárny kľúč
Agregovanie a primárny kľúč
usersid name email country_id1 fan123 [email protected] 12 johnny [email protected] 4
ratingsuser_id film_id rating
1 1 101 6 21 7 82 2 92 12 4
Chceme počet hodnotení od tých používaľov, čo hodnotili.
Agregovanie dát Agregovanie a primárny kľúč
Agregovanie a primárny kľúč
Chceme počet hodnotení od tých používaľov, čo hodnotili.
SELECT user_id, count(*)FROM ratingsGROUP BY user_id
user_id count1 32 2
Agregovanie dát Agregovanie a primárny kľúč
Agregovanie a primárny kľúč
Čo ak chceme namiesto user_id získať users.name ?
SELECT users.name, count(*)FROM ratingsINNER JOIN users ON users.id = ratings.user_idGROUP BY users.id
Agregovanie dát Agregovanie a primárny kľúč
Agregovanie a primárny kľúč
SELECT users.name, count(*)FROM ratingsINNER JOIN users ON users.id = ratings.user_idGROUP BY users.id
Štandardne dostaneme chybu:
ERROR: column "users.name" must appear in the GROUP BYclause or be used in an aggregate function
Databázový systém nevie garantovať, že pre jedno users.id existuje ibajedno users.name
Agregovanie dát Agregovanie a primárny kľúč
Agregovanie a primárny kľúč
Ak ale bude users.id primárnym kľúčom tabuľky user:I nemôžeme mať dvoch user-ov s tým istým id (ani NULL),I a teda pre jedno users.id existuje iba jedno users.name
Teraz môžeme users.name v SELECT časti použiť:
SELECT users.name, count(*)FROM ratingsINNER JOIN users ON users.id = ratings.user_idGROUP BY users.id
name countfan123 3johnny 2
Agregovanie dát Poradie agregovania
Pri niektorých agregač. funkciach záleží na poradí riadkov
string_agg(výraz, oddeľovač)
I pre každý riadok vyhodnotí výraz a všetky hodnoty spojíoddeľovačom do jedného reťazca
Agregovanie dát Poradie agregovania
Pri niektorých agregač. funkciach záleží na poradí riadkov
excercise_tagexcercise_id tag
1 join1 aggregation2 join2 subselect3 subselect3 join
Agregovanie dát Poradie agregovania
Pri niektorých agregač. funkciach záleží na poradí riadkov
SELECT excercise_id,string_agg(tag, ’,’) AS excercise_type
FROM excercise_tagGROUP BY excercise_id
excercise_id excercise_type1 join,aggregation2 join,subselect3 subselect,join
Agregovanie dát Poradie agregovania
ORDER BY
názov_agregačnej_funkcie(parametre ORDER BY order_by_výraz)
I pred tým než na riadky aplikuje agregačnú funkciu riadky usporiadapodľa výrazu
Agregovanie dát Poradie agregovania
Pri niektorých agregač. funkciach záleží na poradí riadkov
SELECT excercise_id,string_agg(tag, ’,’ ORDER BY tag) AS excercise_type
FROM excercise_tagGROUP BY excercise_id
excercise_id excercise_type1 aggregation,join2 join, subselect3 join, subselect
Agregovanie dát Poradie agregovania
ORDER BY
I ORDER BY funguje na všetkých štandardných agregačných funkciachI niekedy jeho použitie ale nemá zmysel
SELECT max(value ORDER BY value)FROM data
Agregovanie dát SELECT – Rekapitulácia
SELECT – Rekapitulácia
1. vyhodnotí sa FROM – JOINovaním vznikne jedna veľká tabuľka2. aplikuje sa WHERE – ostanú iba riadky vyhovujúce podmienke3. vytvoria sa skupiny podľa GROUP BY
4. aplikujú sa agreg. funkcie a každá skupina sa redukuje na jeden riadok5. aplikuje sa HAVING – ostanú iba riadky vyhovujúce podmienke6. výsledok sa usporiada podľa ORDER BY
7. vyhodia sa duplicity podľa DISTINCT (ON)
8. riadkom sa priradia poradové čísla9. vyberú sa riadky s poradovými číslami podľa LIMIT a OFFSET
Viac zoskupovaní naraz
Section 3
Viac zoskupovaní naraz
Viac zoskupovaní naraz
Motivačný príklad – Superagregácia
paymentsuser_id date payment
1 ... 203 ... 52 ... 233 ... 202 ... 183 ... 204 ... 70
Viac zoskupovaní naraz
Motivačný príklad – Superagregácia
user_id total_payment1 202 413 454 70
176
Posledný riadok sa nazýva superagregačný.
Viac zoskupovaní naraz
Ručné riešenie
SELECT user_id, sum(payment) AS total_paymentFROM paymentsGROUP BY user_id
UNION ALL
SELECT NULL, sum(payment) AS total_paymentFROM payments
Viac zoskupovaní naraz
GROUPING SETS
... GROUP BYGROUPING SETS (grouping_set_1, ..., grouping_set_n)
kde grouping_set_i je
(názov_stĺpca_i_1, ..., názov_stĺpca_i_m)
Viac zoskupovaní naraz
Riešenie cez GROUPING SETS
SELECT user_id, sum(payment) AS total_paymentFROM paymentsGROUP BY GROUPING SETS ( (user_id), () )I najpv sa robí agregácia GROUP BY (user_id)I potom sa robí agregácia GROUP BY () – nad celou tabuľkouI za stĺpce, ktoré v danej grouping set nie sú, ale sú v inej grouping set
sa dosadí NULLI výsledky sa zjednotia
Viac zoskupovaní naraz
Riešenie cez GROUPING SETS
user_id date payment1 ... 203 ... 52 ... 233 ... 20... ... ...
SELECT user_id, sum(payment) AS total_paymentFROM paymentsGROUP BY GROUPING SETS ( (user_id), () )
user_id total_payment1 202 413 454 70
NULL 176
Viac zoskupovaní naraz
Ďalší príklad
user_id brand size payment1 Banana M 203 Hot shirts and son L 52 Banana S 233 Hot shirts and son S 20
SELECT brand, size, sum(payment) AS total_paymentFROM paymentsGROUP BY GROUPING SETS ( (brand), (size) )
brand size total_paymentBanana NULL 43
Hot shirts and son NULL 25NULL M 20NULL L 5NULL S 43
Viac zoskupovaní naraz
GROUPING SETS – násobenie, vnáranie a zátvorkovanie
http://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-GROUPING-SETS
Viac zoskupovaní naraz
Rôzne príčiny NULL hodnôt
user_id brand size payment1 Banana M 203 Hot shirts and son L 52 Banana S 233 NULL S 20
SELECT brand, sum(payment) AS total_paymentFROM paymentsGROUP BY GROUPING SETS ( (brand), () )
brand sumBanana 43
Hot shirts and son 5NULL 20NULL 68
Viac zoskupovaní naraz
Funkcia GROUPING
GROUPING(výraz_1, ..., výraz_n)
I jednotlivé výrazy sa nevyhodnocujúI pre každý riadok vracia bitovú masku, ktorá hovoríI či je daný riadok superagregačný pre jednotlivé výrazy
Viac zoskupovaní naraz
Funkcia GROUPING
user_id brand size payment1 Banana M 203 Hot shirts and son L 52 Banana S 233 NULL S 20
SELECT brand,sum(payment),GROUPING(brand)
FROM paymentsGROUP BY GROUPING SETS ( (brand), () )
brand sum groupingBanana 43 0b0
Hot shirts and son 5 0b0NULL 20 0b0NULL 68 0b1
Viac zoskupovaní naraz
Funkcia GROUPINGSELECT brand,
sum(payment),GROUPING(brand) AS g_b,GROUPING(size) AS g_s,GROUPING(brand, size) AS g_bs
FROM paymentsGROUP BY GROUPING SETS ( (brand), (size), () )
brand size sum g_b g_s g_bsBanana NULL 43 0b0 0b1 0b01
Hot shirts and son NULL 5 0b0 0b1 0b01NULL NULL 20 0b0 0b1 0b01NULL NULL 68 0b1 0b1 0b11NULL l 5 0x1 0b0 0b10NULL m 20 0b1 0b0 0b10NULL s 43 0b1 0b0 0b10
Viac zoskupovaní naraz
Funkcia GROUPING
SELECT CASEWHEN GROUPING(brand) = 1 THEN ’all’ELSE brand
END AS brand,sum(payment)
FROM paymentsGROUP BY GROUPING SETS ( (brand), () )
brand sumBanana 43
Hot shirts and son 5NULL 20all 68
Viac zoskupovaní naraz
Komplikácia
I ak zoskupujeme podľa idčiekI a názvy potrebujeme dotiahnut z iných tabuliek
I riešenie vyžaduje subSELECTI čo je mimo rozsahu tejto prednášky
Viac zoskupovaní naraz
Koniec
Koniec