Pouze tento týden sleva až 80 % na e-learning týkající se Javy. A zároveň využij akce až 30 % zdarma při nákupu e-learningu - Více informací.
Hledáme koordinátorku kurzů a programátora, 100% home office, 100% flexibilní. Prozkoumej aktuální pozice
Java week

Lekce 7 - Oracle krok za krokem: Řazení, Fetch a agregační funkce

V minulé lekci, Oracle krok za krokem: Výběr dat (vyhledávání), jsme si připravili testovací data a naučili se základy dotazování, tedy příkaz SELECT a několik operátorů.

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;
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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

Příště si v lekci Oracle krok za krokem: Datové typy a NULL řekneme něco o hodnotě NULL a představíme si tabulku datových typů v Oracle DB.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 58x (1.78 kB)

 

Předchozí článek
Oracle krok za krokem: Výběr dat (vyhledávání)
Všechny články v sekci
Oracle
Přeskočit článek
(nedoporučujeme)
Oracle krok za krokem: Datové typy a NULL
Článek pro vás napsal Matěj Kadlec
Avatar
Uživatelské hodnocení:
Ještě nikdo nehodnotil, buď první!
Autor se programování věnuje od střední školy, nyní studuje informatiku na VŠB-TUO. Mezi jeho oblíbené jazyky patří Python, C# a SQL.
Aktivity

 

 

Komentáře

Avatar
Dadoš
Člen
Avatar
Dadoš:9.7.2021 15:53

Nezdá se mi, že by FETCH a ORDER BY šlo použít u příkazů DELETE a UPDATE.... Jseš si istý? Můžeš uvést příklad?

 
Odpovědět
9.7.2021 15:53
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Matěj Kadlec
Člen IT Redactor Gang
Avatar
Matěj Kadlec:9.7.2021 20:06

Ahoj, máš pravdu, s UPDATE ani DELETE nejde FETCH použít přímo, možné použití by mohlo být maximálně například

DELETE FROM tabulka WHERE id IN (SELECT id FROM tabulka FETCH FIRST ROW ONLY)

V článku to ale takto uvedeno není, a ani nedává smysl aby to tam bylo, jelikož to je prostě obyčejné použití se SELECT, tedy tuto zmínku z článku vypustím, děkuji za upozornění.

 
Odpovědět
9.7.2021 20:06
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.