7. diel - Oracle krok za krokom: Radenie, Fetch a agregačné funkcie
V predchádzajúcom cvičení, Riešené úlohy k 1.-5. lekciu Oracle, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
Dnes sa pozrieme na radenie a agregačné funkcie.
Radenie
Doteraz sme nijako neriešili poradie nájdených výsledkov, ktoré nám
dotaz SELECT
vrátil. Ono vlastne žiadne ani neexistovalo,
databázy vnútri funguje pomocou určitých sofistikovaných pravidiel (ktoré
sú nad rámec tohto seriálu) a vrátila nám položky tak, ako sa jej to
zrovna hodilo. Keby sme v databáze vykonali nejakú zmenu a zavolali znova ten
istý dotaz, poradie by pravdepodobne vyzeralo úplne inak. Databáza nám ale
navrátený výsledok samozrejme zoradiť dokáže.
Radiť môžeme podľa ktoréhokoľvek stĺpca. Keď budeme radiť podľa ID,
máme položky v poradí, v akom boli do databázy vložené. Ďalej môžeme
radiť podľa číselných stĺpcov, ale aj podľa tých textových (radí sa
podľa abecedy). Radiť môžeme aj podľa dátumu a všetkých ďalších
dátových typov, databázy si s tým vždy nejako poradia. Poďme si vybrať
úplne všetkých užívateľov a zoradí ich podľa priezviska. Slúži na to
klauzuly ORDER BY
(radiť podľa), ktorá sa píše na koniec
dotazu:
SELECT jmeno, prijmeni FROM uzivatele ORDER BY prijmeni;
výsledok:
MENO | PRIEZVISKO |
---|---|
Václav | Blažek |
Ondřej | bohatý |
Vítězslav | Churý |
marie | čierna |
Petr | Čierny |
pavel | Dušín |
... | ... |
WHERE
, pre jednoduchosť sme
vybrali všetkých užívateľov.
Radiť môžeme podľa niekoľkých kritérií (stĺpcov), poďme si užívateľa zoradiť podľa napísaných článkov a tie s rovnakým počtom řaďme ešte podľa abecedy:
SELECT jmeno, prijmeni, pocet_clanku FROM uzivatele ORDER BY pocet_clanku, prijmeni;
výsledok:
MENO | PRIEZVISKO | POCET_CLANKU |
---|---|---|
Matěj | Horák | 0 |
michal | Krejčí | 0 |
Petr | Čierny | 1 |
miroslav | Kučera | 1 |
Vladimír | pokorný | 1 |
Jana | Veselá | 1 |
... | ... | ... |
Určiť môžeme samozrejme aj smer radenia. Môžeme radiť vzostupne
(predvolené smer) kľúčovým slovom ASC
(angl. ASCENDING) a
zostupne kľúčovým slovom DESC
(angl. Descending). Skúsme si
urobiť rebríček užívateľov podľa počtu článkov. Tí prví ich teda
majú najviac, radiť budeme zostupne. Tie sa rovnakým počtom článkov budeme
radiť ešte podľa abecedy:
SELECT jmeno, prijmeni, pocet_clanku FROM uzivatele ORDER BY pocet_clanku DESC, prijmeni;
výsledok:
MENO | PRIEZVISKO | POCET_CLANKU |
---|---|---|
Petr | Dvořák | 18 |
Jan | Novák | 17 |
eva | Kučerová | 12 |
Tomáš | márny | 12 |
pavel | Dušín | 9 |
Otakar | Kovář | 9 |
... | ... | ... |
DESC
treba vždy uviesť. Vidíte, že zoradenie podľa priezviska
je normálne zostupnej, pretože sme DESC
napísali len k stĺpci
pocet_clanku.
Fetch
Zostaňme ešte u nášho rebríčka užívateľov podľa počtu článkov.
Takto budeme chcieť vypísať 10 najlepších užívateľov. Keď ich bude ale
milión, asi nie je dobrý nápad je všetky vybrať a potom ich v aplikácii
použiť len 10 a tých 999 990 zahodiť. S využitím FETCH FIRST
databázu povieme, koľko záznamov chceme vybrať. Zároveň uvedieme i
radenie. FETCH
píšeme vždy na koniec dotazu:
SELECT jmeno, prijmeni, pocet_clanku FROM uzivatele ORDER BY pocet_clanku DESC FETCH FIRST 10 ROWS ONLY;
Skúste si to.
FETCH
a ORDER BY
možné používať aj u
ďalších príkazov, napr. U DELETE
alebo UPDATE
.
Môžeme si tak poistiť, aby bol vymazaný alebo editovaný vždy len jeden
záznam.
Agregačné funkcie
Databáza nám ponúka množstvo tzv. Agregačných funkcií. To sú funkcie, ktoré nejakým spôsobom spracujú viac hodnôt a ako výsledok vráti hodnotu jednu.
COUNT()
Príkladom takejto funkcie je funkcia COUNT()
, teda počet,
ktorá vráti počet riadkov v tabuľke, spĺňajúce nejaká kritériá.
Spočítajme, koľko z užívateľov popísalo aspoň jeden článok:
SELECT COUNT(*) FROM uzivatele WHERE pocet_clanku > 0;
výsledok:
COUNT (*) |
---|
29 |
COUNT
sa pýtame pomocou SELECT
, nie je to
príkaz, je to funkcia, ktorá sa vykoná nad riadky a jej výsledok je
vrátený SELECT. Funkcia má rovnako ako v iných programovacích jazykoch
(aspoň vo väčšine z nich) zátvorky. Tá hviezdička v nich znamená, že
nás zaujímajú všetky stĺpce. Môžeme totiž počítať napríklad len
používateľov, ktorí majú vyplnené meno (presnejšie ktorí ho nemajú
NULL
, ale to nechajme na ďalšie diely).
Určite by vás napadol aj iný spôsob, ako tento výsledok docieliť. Jednoducho by ste si vybrali nejakú hodnotu ako doteraz (napríklad meno), tieto riadky by ste si preniesli do svojej aplikácie a spočítali, koľko mien je. Dáta by ste potom zahodili. Taký prenos je ale zbytočne náročný na databázu a spomaľoval by aplikáciu. COUNT prenáša len jedno jediné číslo. Nikdy nepočítajte pomocou výberu hodnoty, iba funkcií COUNT!
AVG()
AVG
označuje priemer z daných hodnôt. Pozrime sa, aký je
priemerný počet článkov na užívateľa:
SELECT AVG(pocet_clanku) FROM uzivatele;
výsledok:
AVG (pocet_clanku) |
---|
5.3225 ... |
SUM()
SUM
vracia súčet hodnôt. Pozrime sa, koľko článkov
napísali dohromady ľudia narodení po roku 1980:
SELECT SUM(pocet_clanku) FROM uzivatele WHERE datum_narozeni > '1.1.1980';
výsledok:
SUM (pocet_clanku) |
---|
65 |
MIN()
Funkcia MIN()
vráti minimum (najmenšiu hodnotu). Nájdime
najnižšej dátum narodenia:
SELECT MIN(datum_narozeni) FROM uzivatele;
výsledok:
MIN (datum_narozeni) |
---|
15.05.35 |
-- Tento kód nebude fungovat SELECT jmeno, prijmeni, MIN(datum_narozeni) FROM uzivatele;
Agregačné funkcie pracuje s hodnotami viac stĺpcov a vybrané stĺpce
(meno a priezvisko) nebudú nijako súvisieť s hodnotou MIN()
.
Problém by sme mohli vyriešiť poddotazov alebo ešte jednoduchšie sa
funkciám MIN()
a MAX()
úplne vyhnúť a použiť
namiesto nich radenia a FETCH
:
SELECT jmeno, prijmeni, datum_narozeni FROM uzivatele ORDER BY datum_narozeni FETCH FIRST ROW ONLY;
výsledok:
MENO | PRIEZVISKO | DATUM_NAROZENI |
---|---|---|
Alfons | sloboda | 15.05.35 |
MAX()
Obdobne ako MIN
existuje aj funkcia MAX
, nájdime
maximálny počet článkov od 1 užívateľa:
SELECT MAX(pocet_clanku) FROM uzivatele;
výsledok:
MAX (POCET_CLANKU) |
---|
18 |
GROUP BY
)
Položky v databáze môžeme zoskupovať podľa určitých kritérií. Zoskupovanie používame takmer vždy spolu s agregačními funkciami. Poďme zoskupiť užívateľa podľa mena:
SELECT jmeno FROM uzivatele GROUP BY jmeno ORDER BY jmeno;
výsledok:
MENO |
---|
Alfons |
eva |
František |
Jan |
Jana |
... |
COUNT(*)
:
SELECT jmeno, COUNT(*) FROM uzivatele GROUP BY jmeno ORDER BY jmeno;
výsledok:
MENO | COUNT (*) |
---|---|
Alfons | 1 |
eva | 1 |
František | 1 |
Jan | 2 |
Jana | 1 |
AS
Pre zjednodušenie si môžeme v dotaze vytvoriť aliasy, teda premenovať
napríklad nejaký dlhý stĺpec, aby bol dotaz prehľadnejšie. S týmto sa
ešte stretneme u otázok cez viac tabuliek, kde je to veľmi užitočné. U
tabuliek AS
používame na zjednodušenie operácií vo vnútri
dotazu. U stĺpcov sa AS
používa k tomu, aby aplikácia videla
dáta pod iným názvom, ako sú skutočne v databáze. To môže byť
užitočné najmä u agregačných funkcií, pretože pre nich v databáze nie
je žiadny stĺpec a mohlo by sa nám s ich výsledkom zle pracovať. Upravme si
posledný otázka:
SELECT jmeno, COUNT(*) AS pocet FROM uzivatele GROUP BY jmeno;
výsledok:
MENO | POCET |
---|---|
Matěj | 1 |
miroslav | 1 |
František | 1 |
Josef | 1 |
Jana | 1 |
marie | 1 |
Nabudúce si v lekcii Oracle krok za krokom: Dátové typy a NULL povieme niečo o hodnote NULL a predstavíme si tabuľku dátových typov v Oracle DB.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkamiStiahnuté 276x (1.78 kB)