Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Architektury a techniky DS Cvičení č. 3 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky

Podobné prezentace


Prezentace na téma: "Architektury a techniky DS Cvičení č. 3 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky"— Transkript prezentace:

1 Architektury a techniky DS Cvičení č. 3 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky david.zak@upce.cz david.zak@upce.cz

2 Analytické funkce Stále vyšší využití databázových systémů pro evidování veškerých možných aktivit a rostoucí požadavky manažerů na sledování různých kritérií si vyžádaly zavedení dalších funkcí, které rozšířily kategorie agregačních funkcí SUM, COUNT, AVG, MIN, MAX. Tato nová skupina funkcí překračuje hranice ANSI SQL a je proto závislá na konkrétní databázové platformě. V tomto cvičení popsané příklady pracují na platformě Oracle (zhruba od verze 9). Uvedené příklady lze vyzkoušet na schématu A_HR.

3 Analytické funkce Uvědomíme-li si rozdíl mezi skupinovými funkcemi a analytickými funkcemi, pak výsledkem skupinového dotazu jsou pouze seskupené výsledky, např. SELECT ODDELENI_ID, COUNT(*) POCET_ZAM FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) GROUP BY ODDELENI_ID; U analytických funkcí mohou být ve výsledku i „neseskupené“ sloupce, např. SELECT ZAMESTNANEC_ID, ODDELENI_ID, COUNT(*) OVER (PARTITION BY ODDELENI_ID) POCET_ZAM FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) Analytické funkce jsou kalkulovány až po provedení všech spojení a omezení, těsné před provedením klauzule ORDER BY. ODDELENI_IDPOCET_ZAM 202 306 ZAMESTNANEC_IDODDELENI_IDPOCET_ZAM201202 202202 114306 115306 116306 117306 118306 119306

4 Analytické funkce V předchozím příkladě klauzule PARTITION BY je použita pro rozdělení dotazem vygenerovaných řádků do skupin (v našem případě např. podle ODDELENI_ID ). Některé analytické funkce podporují vymezení okna uvnitř klauzule PARTITION BY pro omezení počtu řádků, na něž se vztahují. Pokud okno není vymezeno, je analytická funkce kalkulována ze všech řádků v dané skupině. U funkcí SUM, COUNT, AVG, MIN, MAX je jejich výsledek nezávislý na pořadí řádků. Funkce LEAD, LAG, RANK, DENSE_RANK, ROW_NUMBER, FIRST, FIRST VALUE, LAST, LAST VALUE jsou závislé na pořadí řádků, tedy na jejich řazení klauzulí ORDER BY v syntaxi analytické funkce.

5 ROW_NUMBER( ) pořadí ROW_NUMBER( ) vrací pořadí řádku ve skupině záznamů. To je zvláště užitečné v případě reportů, kde má být každá skupina samostatně očíslována. V příkladu je ROW_NUMBER( ) použito k očíslování řádku ve skupině dané číslem oddělení pro oddělení s čísly 10 a 20 v pořadí dle data nástupu. SELECT ZAMESTNANEC_ID, ODDELENI_ID, DATUM_NASTUP, ROW_NUMBER( ) OVER (PARTITION BY ODDELENI_ID ORDER BY DATUM_NASTUP NULLS LAST) PORADI FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) ORDER BY ODDELENI_ID, PORADI; ZAMESTNANEC_IDODDELENI_IDDATUM_NASTUPPORADI 2012017.2.19961 2022017.8.19972 114307.12.19941 1153018.5.19952 1173024.7.19973 1163024.12.19974 1183015.11.19985 1193010.8.19996

6 ROW_NUMBER, RANK a DENSE_RANK Tyto funkce vrací celá čísla v závislosti na pořadí řádků. RANK a DENSE_RANK obě vrací pořadí hodnoty v daném řádku v závislosti na hodnotě v nějakém sloupci nebo hodnotě výrazu. V případě nerozhodnosti mezi 2 záznamy na pozici N, RANK vyhlásí 2 pořadí N a přeskočí pozici N+1, další řádek pak označí pozicí N+2. DENSE_RANK v takovém případě vyhlásí 2 pořadí N, ale nepřeskočí pozici N+1 (tedy další řádek bude s pozicí N+1). Příklad ukazuje využití obou funkcí RANK a DENSE_RANK. Rozdíl je zřejmý na posledním řádku, neboť na předchozí 3. pozici v oddělení s i ODDELENI_ID=60 mají 2 zaměstnanci shodný plat. SELECT ZAMESTNANEC_ID, ODDELENI_ID, MZDA, RANK() OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA DESC NULLS LAST) RANK, DENSE_RANK() OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA DESC NULLS LAST) DENSE_RANK FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 60) ORDER BY 2, RANK; ZAMESTNANEC_IDODDELENI_IDMZDARANKDENSE_RANK 201201300011 20220600022 10360900011 10460600022 10560480033 10660480033 10760420054

7 LEAD, LAG Funkce LEAD má schopnost kalkulovat výraz na základě hodnot ve sloupcích některého z následujících řádků (zobrazených po daném řádku) a vrátit hodnotu do daného řádku. Obecná syntaxe LEAD je: LEAD (,, ) OVER ( ) je výraz kalkulovaný z následujících řádků kladné celé číslo, defaultně 1 (index následujícího řádku vzhledem k řádku aktuálnímu) je hodnota vracená v případě, kdy ukazuje na řádek mimo vybranou skupinu. je výraz kalkulovaný z následujících řádků kladné celé číslo, defaultně 1 (index následujícího řádku vzhledem k řádku aktuálnímu) je hodnota vracená v případě, kdy ukazuje na řádek mimo vybranou skupinu. Syntaxe LAG ie obdobná, jen se OFFSET vztahuje na předchozí řádky. SELECT ZAMESTNANEC_ID, ODDELENI_ID, MZDA, LEAD(MZDA, 1, 0) OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA DESC NULLS LAST) NEXT_LOWER_SAL, LAG(MZDA, 1, 0) OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA DESC NULLS LAST) PREV_HIGHER_SAL FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) ORDER BY ODDELENI_ID, MZDA DESC; ZAMESTNANEC_IDODDELENI_IDMZDANEXT_LOWER_SALPREV_HIGHER_SAL 20120 13000 60000 20220 6000 013000 11430 11000 31000 11530 3100 290011000 11630 2900 28003100 11730 2800 26002900 11830 2600 25002800 11930 2500 02600

8 FIRST VALUE, LAST VALUE Funkce FIRST_VALUE vybere první záznam ze skupiny po provedení ORDER BY. Obecná syntaxe je: FIRST_VALUE( ) OVER ( ) Výraz je vyhodnocen na sloupcích vybraného prvního záznamu a výsledek je vrácen. Funkce LAST_VALUE pracuje obdobně a vybírá poslední záznam ze skupiny. Příklad zjišťuje, kolik dní po nástupu prvního pracovníka na oddělení nastoupili ostatní pracovníci. SELECT ZAMESTNANEC_ID, ODDELENI_ID, DATUM_NASTUP, DATUM_NASTUP – FIRST_VALUE(DATUM_NASTUP) OVER (PARTITION BY ODDELENI_ID ORDER BY DATUM_NASTUP) DNU_MEZIDOBI (PARTITION BY ODDELENI_ID ORDER BY DATUM_NASTUP) DNU_MEZIDOBI FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) ORDER BY ODDELENI_ID, DNU_MEZIDOBI; ZAMESTNANEC_IDODDELENI_IDDATUM_NASTUPDNU_MEZIDOBI 2012017.2.19960 2022017.8.1997547 114307.12.19940 1153018.5.1995162 1173024.7.1997960 1163024.12.19971113 1183015.11.19981439 1193010.8.19991707

9 FIRST a LAST Funkce FIRST je užívána ve velmi speciálních situacích. Předpokládejme, že v rámci dané skupiny máme několik záznamů s prvním pořadím. Nyní chceme aplikovat agregační funkce na všechny záznamy s prvním pořadím. Funkce KEEP FIRST toto umožní. Obecná syntaxe je: Function( ) KEEP (DENSE_RANK FIRST ORDER BY ) OVER ( ) FIRST a LAST jsou jediné funkce, které se odchylují od obecné syntaxe analytických funkcí. Nemají klauzuli ORDER BY uvnitř klauzule OVER, ani nepodporují vymezení okna pomocí window klauzule. Řazení realizované ve FIRST a LAST je vždy DENSE_RANK. Příklad ukazuje využití funkce FIRST (funkce LAST se používá obdobně) pro porovnání platu zaměstnance s průměrným platem zaměstnanců přijatých v prvním roce. SELECT ZAMESTNANEC_ID, ODDELENI_ID, EXTRACT (YEAR FROM DATUM_NASTUP) ROK_NASTUPU, MZDA, TRUNC(AVG(MZDA) KEEP (DENSE_RANK FIRST ORDER BY EXTRACT (YEAR FROM DATUM_NASTUP))OVER (PARTITION BY ODDELENI_ID) ) AVG_MZDA_1_ROK FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 50) ORDER BY ODDELENI_ID, ROK_NASTUPU, ZAMESTNANEC_ID; ZAMESTNANEC_IDODDELENI_IDROK_NASTUPUMZDAAVG_MZDA_1_ROK 2012019961300013000 202201997600013000 12250199579005000 13750199536005000 14150199535005000 12050199680005000 13350199633005000

10 Specifikace Window klauzule Některé analytické funkce (AVG, COUNT, FIRST_VALUE, LAST_VALUE, MAX, MIN, SUM) mohou obsahovat window klauzuli pro další vyčlenění záznamů dané PARTITION a následné aplikování analytických funkcí na tyto vyčleněné záznamy. Celé chování window klauzule je dynamické. Obecná syntaxe je: [ROW or RANGE] BETWEEN AND může být jedna z následujících UNBOUNDED PRECEDING CURRENT ROW PRECEDING nebo FOLLOWING. může být jedna z následujících možností UNBOUNDED FOLLOWING CURRENT ROW PRECEDING nebo FOLLOWING kde hovořící o počtu řádků před či za aktuálním řádkem u ROW type okna.

11 Specifikace Window klauzule Do okna může nebo nemusí být zahrnut aktuální řádek dle hodnot v či. Startovní bod nemůže následovat za koncovým bodem okna. V případě, kdy některý konec okna není definován, je defaultní hodnota UNBOUNDED PRECEDING pro a UNBOUNDED FOLLOWING pro. Jestliže konečným bodem je aktuální řádek, může být uvedena pouze syntaxe startovního bodu [ROW or RANGE] [ PRECEDING or UNBOUNDED PRECEDING ] Pro analytické funkce s oknem typu ROW je obecná syntaxe : Function( ) OVER (PARTITION BY ORDER BY ROWS BETWEEN AND ) nebo Function( ) OVER (PARTITON BY ORDER BY ROWS [ PRECEDING or UNBOUNDED PRECEDING]

12 Klauzule Window typu ROW Příklad – pro každého zaměstnance vrací průměr mzdy 3 zaměstnanců daného oddělení se mzdou nejblíže nižší danému zaměstnanci a průměr mzdy daného a 3 nejblíže více placených zaměstnanců na stejném oddělení jako daný zaměstnanec. SELECT ODDELENI_ID, ZAMESTNANEC_ID, MZDA, trunc(avg(MZDA) OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING)) PRUMER_3_NIZSI, ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING)) PRUMER_3_NIZSI, trunc(avg(MZDA) OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA ROWS BETWEEN CURRENT ROW AND 3 FOLLOWING)) PRUMER_DANY_3_VYSSI ROWS BETWEEN CURRENT ROW AND 3 FOLLOWING)) PRUMER_DANY_3_VYSSI FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) ORDER BY ODDELENI_ID, MZDA; ODDELENI_IDZAMESTNANEC_IDMZDAPRUMER_3_NIZSIPRUMER_DANY_3_VYSSI 2020260009500 2020113000600013000 3011925002700 30118260025002850 30117280025504950 30116290026335666 30115310027667050 3011411000293311000

13 Klauzule Window typu RANGE Pro okno typu RANGE je obecná syntaxe analogická s okny typu ROW. Důležité je si uvědomit, že velikost okna z hlediska počtu řádků se může měnit, neboť důležité je, zda kontrolovaná hodnota leží v požadovaném intervalu.. Příklad – pro každého zaměstnance (v aktuálním řádku) vrací počet zaměstnanců, kteří mají mzdu o 10 a více procent menší, než je plat aktuálního zaměstnance, a kteří mají o 10% až 50% vyšší mzdu. SELECT ODDELENI_ID, ZAMESTNANEC_ID, MZDA, COUNT(*) OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA RANGE BETWEEN UNBOUNDED PRECEDING AND (MZDA*0.1) PRECEDING) o_10pct_MENE, RANGE BETWEEN UNBOUNDED PRECEDING AND (MZDA*0.1) PRECEDING) o_10pct_MENE, COUNT(*) OVER (PARTITION BY ODDELENI_ID ORDER BY MZDA RANGE BETWEEN (MZDA*0.1) FOLLOWING AND (MZDA*0.5) FOLLOWING) o_10_50_pct_VICE RANGE BETWEEN (MZDA*0.1) FOLLOWING AND (MZDA*0.5) FOLLOWING) o_10_50_pct_VICE FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) ORDER BY ODDELENI_ID, MZDA ODDELENI_IDZAMESTNANEC_IDMZDAO_10PCT_MENEO_10_50_PCT_VICE 20202600000 202011300010 30119250003 30118260002 30117280011 30116290020 30115310020 301141100050

14 Cvičení č. 3 - zadání Nad tabulkou LIDE ve schématu A_CLOVEK řešte pomocí analytických funkcí: 1.Vytvořte pohled jmena_pocet se sloupci (id, jmeno, prijmeni, pocet_jmen) pro zjištění počtu osob, které mají stejné jméno jako daná osoba. 2.Vytvořte pohled sourozenci_odstup se sloupci (id, jmeno, prijmeni, id_otce, id_matky, narozen, odstup, poradi) pro zjištění rozdílů mezi daty narození po sobě jdoucích vlastních sourozenců v kalendářních dnech a pořadí, jak byli sourozenci narozeni. 3.Vytvořte pohled bratri_pocet_nejstarsi se sloupci (id, jmeno, prijmeni, id_otce, id_matky, narozen, bratru, starsi_jmeno, nejstarsi_jmeno) pro zjištění počtu vlastních bratrů pro všechny muže a jména nejblíže staršího a nejstaršího z nich. 4.Vytvořte pohled vnoucata_pocet_starsich se sloupci (id, jmeno, prijmeni, id_babicky, narozen, vnoucata_3r_starsi_pocet, vnoucata_3r_starsi_vek) pro zjištění počtu ostatních vnoučat Boženy Malé, která jsou o 3 roky starší než dané vnouče a průměrný věk s přesností na jedno desetinné místo těchto o 3 roky starších vnoučat. 5.Vybrané 2 příklady řešte také klasicky, bez použití analytických funkcí. Tyto pohledy označte příponou _klas za původním názvem pohledu.

15 Doplnění hierarchických dotazů • Pro jednotlivé záznamy můžete také získat cestu od nejvyššího záznamu (jak to znáte třeba ze souborového systému) nebo řadu dalších informací: • Funkce SYS_CONNECT_BY_PATH vrací cestu v hierarchii k aktuálnímu záznamu. • Klauzule CONNECT_BY_ROOT vrací hodnotu z příslušného záznamu nejvyšší úrovně (tj. například nejvyššího manažera). • Pokud byste chtěli výstup z dotazu použít pro zobrazení ve formě rozbalovací hierarchie tak, jak to třeba dělá u souborů Windows Explorer, bude se vám hodit i pseudosloupec CONNECT_BY_ISLEAF, který určuje, zda je aktuální záznam na poslední úrovni hierarchie (CONNECT_BY_ISLEAF=1) nebo zda má podřízené záznamy (CONNECT_BY_ISLEAF=0).

16 Příklad hierarchických dotazů SELECT lpad(' ',level*3)||PRIJMENI||' '||JMENO name, SYS_CONNECT_BY_PATH(PRIJMENI, '/') path, CONNECT_BY_ROOT PRIJMENI topmgr, CONNECT_BY_ISLEAF isleaf, level FROM A_HR.ZAMESTNANCI CONNECT BY MANAZER_ID = PRIOR ZAMESTNANEC_ID START WITH MANAZER_ID is null ORDER SIBLINGS BY PRIJMENI; NAMEPATHTOPMGRISLEAFLEVEL King Steven/KingKing01 Cambrault Gerald/King/CambraultKing02 Bates Elizabeth/King/Cambrault/BatesKing13 Bloom Harrison/King/Cambrault/BloomKing13 Fox Tayler/King/Cambrault/FoxKing13 Kumar Sundita/King/Cambrault/KumarKing13 Ozer Lisa/King/Cambrault/OzerKing13 Smith William/King/Cambrault/SmithKing13 De Haan Lex/King/De HaanKing02 Hunold Alexander/King/De Haan/HunoldKing03 Austin David/King/De Haan/Hunold/AustinKing14

17 Otázky Děkuji za pozornost. http://www.orafaq.com/node/55


Stáhnout ppt "Architektury a techniky DS Cvičení č. 3 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky"

Podobné prezentace


Reklamy Google