Lekce 7 - Oracle krok za krokem: Řazení, Fetch a agregační funkce
V předešlém cvičení, Řešené úlohy k 6. lekci Oracle, jsme si procvičili nabyté zkušenosti z předchozích lekcí.
Dnes se podíváme na řazení a agregační funkce.
Řazení
Doposud jsme nijak neřešili pořadí nalezených položek, které nám
dotaz SELECT
vrátil. Ono vlastně žádné ani neexistovalo,
databáze uvnitř funguje pomocí určitých sofistikovaných pravidel (které
jsou nad rámec tohoto seriálu) a vrátila nám položky tak, jak se jí to
zrovna hodilo. Kdybychom v databázi provedli nějakou změnu a zavolali znovu
ten samý dotaz, pořadí by pravděpodobně vypadalo úplně jinak. Databáze
nám ale navrácený výsledek samozřejmě seřadit dokáže.
Řadit můžeme podle kteréhokoli sloupce. Když budeme řadit podle ID,
máme položky v pořadí, v jakém byly do databáze vloženy. Dále můžeme
řadit podle číselných sloupců, ale i podle těch textových (řadí se
podle abecedy). Řadit můžeme i podle datumu a všech dalších datových
typů, databáze si s tím vždy nějak poradí. Pojďme si vybrat úplně
všechny uživatele a seřaďme je podle příjmení. Slouží k tomu klauzule
ORDER BY
(řadit podle), která se píše na konec dotazu:
SELECT jmeno, prijmeni FROM uzivatele ORDER BY prijmeni;
Výsledek:
JMENO | PRIJMENI |
---|---|
Václav | Blažek |
Ondřej | Bohatý |
Vítězslav | Churý |
Marie | Černá |
Petr | Černý |
Pavel | Dušín |
... | ... |
V dotazu by samozřejmě mohlo být i WHERE
, pro jednoduchost
jsme vybrali všechny uživatele.
Řadit můžeme podle několika kritérií (sloupců), pojďme si uživatele seřadit podle napsaných článků a ty se stejným počtem řaďme ještě podle abecedy:
SELECT jmeno, prijmeni, pocet_clanku FROM uzivatele ORDER BY pocet_clanku, prijmeni;
Výsledek:
JMENO | PRIJMENI | POCET_CLANKU |
---|---|---|
Matěj | Horák | 0 |
Michal | Krejčí | 0 |
Petr | Černý | 1 |
Miroslav | Kučera | 1 |
Vladimír | Pokorný | 1 |
Jana | Veselá | 1 |
... | ... | ... |
Směr řazení
Určit můžeme samozřejmě i směr řazení. Můžeme řadit vzestupně
(výchozí směr) klíčovým slovem ASC
(angl. ASCending) a
sestupně klíčovým slovem DESC
(angl. DESCending). Zkusme si
udělat žebříček uživatelů podle počtu článků. Ti první jich tedy
mají nejvíce, řadit budeme sestupně. Ty se stejným počtem článků budeme
řadit ještě podle abecedy:
SELECT jmeno, prijmeni, pocet_clanku FROM uzivatele ORDER BY pocet_clanku DESC, prijmeni;
Výsledek:
JMENO | PRIJMENI | POCET_CLANKU |
---|---|---|
Petr | Dvořák | 18 |
Jan | Novák | 17 |
Eva | Kučerová | 12 |
Tomáš | Marný | 12 |
Pavel | Dušín | 9 |
Otakar | Kovář | 9 |
... | ... | ... |
DESC
je třeba vždy uvést. Vidíte, že řazení podle
příjmení je normálně sestupné, protože jsme DESC
napsali jen
k sloupci pocet_clanku.
Fetch
Zůstaňme ještě u našeho žebříčku uživatelů podle počtu článků.
Takto budeme chtít vypsat 10 nejlepších uživatelů. Když jich bude ale
milion, asi není dobrý nápad je všechny vybrat a pak jich v aplikaci
použít jen 10 a těch 999 990 zahodit. S využitím FETCH FIRST
databázi řekneme, kolik záznamů chceme vybrat. Zároveň uvedeme i řazení.
FETCH
píšeme vždy na konec dotazu:
SELECT jmeno, prijmeni, pocet_clanku FROM uzivatele ORDER BY pocet_clanku DESC FETCH FIRST 10 ROWS ONLY;
Zkuste si to.
Agregační funkce
Databáze nám nabízí spoustu tzv. agregačních funkcí. To jsou funkce, které nějakým způsobem zpracují více hodnot a jako výsledek vrátí hodnotu jednu.
COUNT()
Příkladem takové funkce je funkce COUNT()
, tedy počet,
která vrátí počet řádků v tabulce, splňující nějaká kritéria.
Spočítejme, kolik z uživatelů napsalo alespoň jeden článek:
SELECT COUNT(*) FROM uzivatele WHERE pocet_clanku > 0;
Výsledek:
COUNT(*) |
---|
29 |
Na COUNT
se ptáme pomocí SELECT
, není to
příkaz, je to funkce, která se vykoná nad řádky a její výsledek je
vrácen selectem. Funkce má stejně jako v jiných programovacích jazycích
(alespoň ve většině z nich) závorky. Ta hvězdička v nich znamená, že
nás zajímají všechny sloupce. Můžeme totiž počítat třeba jen
uživatele, kteří mají vyplněné jméno (přesněji kteří ho nemají
NULL
, ale to nechme na další díly).
Určitě by vás napadl i jiný způsob, jak tohoto výsledku docílit. Jednoduše byste si vybrali nějakou hodnotu jako doposud (třeba jméno), tyto řádky byste si přenesli do své aplikace a spočítali, kolik jmen je. Data byste poté zahodili. Takový přenos je ale zbytečně náročný na databázi a zpomaloval by aplikaci. COUNT přenáší jen jedno jediné číslo. Nikdy nepočítejte pomocí výběru hodnoty, pouze funkcí COUNT!
AVG()
AVG
označuje průměr z daných hodnot. Podívejme se, jaký je
průměrný počet článků na uživatele:
SELECT AVG(pocet_clanku) FROM uzivatele;
Výsledek:
AVG(pocet_clanku) |
---|
5.3225... |
SUM()
SUM
vrací součet hodnot. Podívejme se, kolik článků
napsali dohromady lidé narození po roce 1980:
SELECT SUM(pocet_clanku) FROM uzivatele WHERE datum_narozeni > '1.1.1980';
Výsledek:
SUM(pocet_clanku) |
---|
65 |
MIN()
Funkce MIN()
vrátí minimum (nejmenší hodnotu). Najděme
nejnižší datum narození:
SELECT MIN(datum_narozeni) FROM uzivatele;
Výsledek:
MIN(datum_narozeni) |
---|
15.05.35 |
Pozor, pokud bychom chtěli vybrat i jméno a příjmení, tento kód nebude fungovat:
-- Tento kód nebude fungovat SELECT jmeno, prijmeni, MIN(datum_narozeni) FROM uzivatele;
Agregační funkce pracuje s hodnotami více sloupců a vybrané sloupce
(jmeno a prijmeni) nebudou nijak souviset s hodnotou MIN()
.
Problém bychom mohli vyřešit poddotazem nebo ještě jednodušeji se funkcím
MIN()
a MAX()
úplně vyhnout a použít místo nich
řazení a FETCH
:
SELECT jmeno, prijmeni, datum_narozeni FROM uzivatele ORDER BY datum_narozeni FETCH FIRST ROW ONLY;
Výsledek:
JMENO | PRIJMENI | DATUM_NAROZENI |
---|---|---|
Alfons | Svoboda | 15.05.35 |
MAX()
Obdobně jako MIN
existuje i funkce MAX
, najděme
maximální počet článků od 1 uživatele:
SELECT MAX(pocet_clanku) FROM uzivatele;
Výsledek:
MAX(POCET_CLANKU) |
---|
18 |
Seskupování (Grouping,
GROUP BY
)
Položky v databázi můžeme seskupovat podle určitých kritérii. Seskupování používáme téměř vždy spolu s agregačními funkcemi. Pojďme seskupit uživatele podle jména:
SELECT jmeno FROM uzivatele GROUP BY jmeno ORDER BY jmeno;
Výsledek:
JMENO |
---|
Alfons |
Eva |
František |
Jan |
Jana |
... |
Vidíme, že každé jméno je zde zastoupeno jen jednou, i když je v
databázi vícekrát. Přidejme nyní kromě jména i počet jeho zastoupení v
tabulce, uděláme to pomocí agregační funkce COUNT(*)
:
SELECT jmeno, COUNT(*) FROM uzivatele GROUP BY jmeno ORDER BY jmeno;
Výsledek:
JMENO | COUNT(*) |
---|---|
Alfons | 1 |
Eva | 1 |
František | 1 |
Jan | 2 |
Jana | 1 |
Vidíme, že třeba Jany máme v databázi dva.
AS
Pro zjednodušení si můžeme v dotazu vytvořit aliasy, tedy přejmenovat
třeba nějaký dlouhý sloupec, aby byl dotaz přehlednější. S tímto se
ještě setkáme u dotazů přes více tabulek, kde je to velmi užitečné. U
tabulek AS
používáme ke zjednodušení operací uvnitř dotazu.
U sloupců se AS
používá k tomu, aby aplikace viděla data pod
jiným názvem, než jsou skutečně v databázi. To může být užitečné
zejména u agregačních funkcí, protože pro ně v databázi není žádný
sloupec a mohlo by se nám s jejich výsledkem špatně pracovat. Upravme si
poslední dotaz:
SELECT jmeno, COUNT(*) AS pocet FROM uzivatele GROUP BY jmeno;
Výsledek:
JMENO | POCET |
---|---|
Matěj | 1 |
Miroslav | 1 |
František | 1 |
Josef | 1 |
Jana | 1 |
Marie | 1 |
V následujícím cvičení, Řešené úlohy k 7. lekci Oracle, si procvičíme nabyté zkušenosti z předchozích lekcí.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkamiStaženo 282x (1.78 kB)