Architektury a techniky DS

Slides:



Advertisements
Podobné prezentace
Aplikační a programové vybavení
Advertisements

KIV/ZIS Cvičení 6 SQL - SELECT.
MS ACCESS - DOTAZY DATABÁZOVÉ SYSTÉMY.
Databáze Dotazy.
Základy jazyka SQL Jan Tichava
DB1 – 9. cvičení Optimalizace dotazu Konkurenční přístup a deadlock Indexace Transakce.
Fakulta elektrotechniky a informatiky
Informační systémy Nástroje pro sběr dat, návrh a realizace databáze.
AGREGACE Distinct, Group By, Having, SUM, …. DISTINCT  Slučování stejných řádků ve výsledku dotazu. AGREGACE 2 JménoPříjmeníID FrantišekVomáčka1 JosefPokorný2.
Další dotazy SQL Structured Query Language. Některé SQL příkazy mohou mít v sobě obsaženy další kompletní příkazy SELECT. Využijeme je tam, kde potřebujeme.
SQL Structured Query Language
Informatika pro ekonomy II přednáška 11
Architektury a techniky DS Tvorba efektivních příkazů I Přednáška č. 3 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Architektury a techniky DS
Architektury a techniky DS Cvičení č. 4 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy 1 Cvičení č. 6 Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Databázové systémy 1 Cvičení č. 4 Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Databázové systémy 1 Cvičení č. 2 Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Databázové systémy I Přednáška č. 5 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy II Přednáška č. 6 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy 1 Cvičení č. 3 Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Temporální databáze a TSQL
MySQL - Vytvoření nové tabulky  create table jméno_tabulky (jméno_položky typ_položky,... ) Přehled nejběžnějších datových typů Přehled nejběžnějších.
Databázové systémy 2 Cvičení č. 7 Ing. Tomáš Váňa Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Školení správců II. Petr Pinkas RNDr. Vít Ochozka.
Databázové systémy II Přednáška č. 9 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Fakulta elektrotechniky a informatiky
Databázové systémy I Cvičení č. 9 Fakulta elektrotechniky a informatiky Univerzita Pardubice 2013.
Databázové systémy 2 Zkouška – 8:00. Příklad I - Funkce Vytvořte funkci ZK_HR_ODDELENI (p_oddeleni_id NUMBER). Funkce vrátí řetězec, obsahující.
KIV/ZIS cvičení 6 Tomáš Potužák. Pokračování SQL Klauzule GROUP BY a dotazy nad více tabulkami Stáhnout soubor studenti_dotazy_sql.mdb.
MS ACCESS parametrický dotaz
Databázové systémy 2 Cvičení č. 4 Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Databázové systémy I Cvičení č. 6 Fakulta elektrotechniky a informatiky Univerzita Pardubice 2013.
Databázové systémy Přednáška č. 6.
SQL – základní pojmy Ing. Roman Danel, Ph.D.
SQL PVA Jan Hora. SQL „graficky“ Grafický vs. pravý SQL SELECT ORDED BY WHERE.
Databázové systémy 2 Cvičení č. 6 Ing. Tomáš Váňa Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Fakulta elektrotechniky a informatiky
Fakulta elektrotechniky a informatiky
Databázové systémy 2 Zkouška – 08:00. Příklad I – Funkce – 4 body Vytvořte funkci F_ZK1(p_id_zamestnance NUMBER) RETURN VARCHAR2. Daná funkce.
Databázové systémy I Cvičení č. 8 Fakulta elektrotechniky a informatiky Univerzita Pardubice 2013.
Architektury a techniky DS Cvičení č. 9 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy 2 Cvičení č. 10 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy II Cvičení č. 3 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy I Cvičení č. 10 Fakulta elektrotechniky a informatiky Univerzita Pardubice 2013.
Databázové systémy 2 Zkouška – 8:00. Příklad I – Procedura – 5 bodů Vytvořte proceduru P_ZK4(p_oddeleni_id_from NUMBER, p_oddeleni_id_to NUMBER)
Databázové systémy I Cvičení č. 7 Fakulta elektrotechniky a informatiky Univerzita Pardubice 2013.
Databázové systémy 2 Zkouška – 8:00. Příklad I – Procedura – 5 bodů Vytvořte proceduru P_ZK2(p_table_name VARCHAR2, p_min_nuls NUMBER, p_drop.
Aplikační a programové vybavení
Architektury a techniky DS Cvičení č. 5 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy 2 Cvičení č. 5 Fakulta elektrotechniky a informatiky Univerzita Pardubice.
XQuery Dotazovací jazyk XML Daniel Privalenkov. O čem bude prezentace Nutnost dotazovacího jazyku v XML Rychlý přehled XQuery Několik příkladů.
Databázové systémy SQL Výběr dat.
 Agregační funkce  Agregační funkce jsou to funkce, které nějakým způsobem zpracují více hodnot a jako výsledek vrátí hodnotu jednu COUNT()  Funkce.
Databázové systémy 2 Zkouška – 8:00. Příklad I - Procedura Vytvořte proceduru PROCEDURE ZK_ZAM_HISTOGRAM(P_ROK_OD IN NUMBER, P_ROK_DO IN NUMBER)
Použití dotazu jako zdroj dat pro pohled Vypracovala: Procházková Petra.
Databázové systémy 2 Cvičení IV Ing. Tomáš Váňa Fakulta elektrotechniky a informatiky
Databázové systémy 2 Zkouška – 8:00. Příklad I - Funkce Vytvořte funkci ZK_DIFF_MIN_MAX (P_ZAM_ID NUMBER) RETURN VARCHAR2. Funkce může vracet.
Administrace Oracle Paralelní zpracování.
Databázové systémy 1 Cvičení č. 5 Fakulta elektrotechniky a informatiky Univerzita Pardubice.
Databázové systémy I Cvičení č. 8 Fakulta elektrotechniky a informatiky Univerzita Pardubice 2015.
Databázové systémy I Přednáška č. 6 RNDr. David Žák, Ph.D. Fakulta elektrotechniky a informatiky
Databázové systémy II Přednáška č. IX Ing. Tomáš Váňa, Ing. Jiří Zechmeister Fakulta elektrotechniky a informatiky
SQL – příkaz SELECT Ing. Roman Danel, Ph.D.
Databázové systémy I Přednáška 5 Databázové systémy 1 – KIT/IDAS1
Databázové systémy I Přednáška 8 Databázové systémy 1 – KIT/IDAS1
Ing. Tomáš Váňa, Ing. Jiří Zechmeister
Databázové systémy a SQL
[ START WITH podmínka ] CONNECT BY podmínka
Optimalizace SQL dotazů
Transkript prezentace:

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

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.

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 Analytické funkce jsou kalkulovány až po provedení všech spojení a omezení, těsné před provedením klauzule ORDER BY. ODDELENI_ID POCET_ZAM 20 2 30 6 ZAMESTNANEC_ID ODDELENI_ID POCET_ZAM 201 20 2 202 114 30 6 115 116 117 118 119

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.

ROW_NUMBER( ) 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_ID ODDELENI_ID DATUM_NASTUP PORADI 201 20 17.2.1996 1 202 17.8.1997 2 114 30 7.12.1994 115 18.5.1995 117 24.7.1997 3 116 24.12.1997 4 118 15.11.1998 5 119 10.8.1999 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_ID ODDELENI_ID MZDA RANK DENSE_RANK 201 20 13000 1 202 6000 2 103 60 9000 104 105 4800 3 106 107 4200 5 4

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 (<sql_expr>, <offset>, <default>) OVER (<analytic_clause>) <sql_expr> je výraz kalkulovaný z následujících řádků <offset> kladné celé číslo, defaultně 1 (index následujícího řádku vzhledem k řádku aktuálnímu) <default> je hodnota vracená v případě, kdy <offset> 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_ID ODDELENI_ID MZDA NEXT_LOWER_SAL PREV_HIGHER_SAL 201 20 13000 6000 202 114 30 11000 3100 115 2900 116 2800 117 2600 118 2500 119

FIRST VALUE, LAST VALUE Funkce FIRST_VALUE vybere první záznam ze skupiny po provedení ORDER BY. Obecná syntaxe je: FIRST_VALUE(<sql_expr>) OVER (<analytic_clause>) Výraz <sql_expr> 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 FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) ORDER BY ODDELENI_ID, DNU_MEZIDOBI; ZAMESTNANEC_ID ODDELENI_ID DATUM_NASTUP DNU_MEZIDOBI 201 20 17.2.1996 202 17.8.1997 547 114 30 7.12.1994 115 18.5.1995 162 117 24.7.1997 960 116 24.12.1997 1113 118 15.11.1998 1439 119 10.8.1999 1707

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 <expr>) OVER (<partitioning_clause>) 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_ID ODDELENI_ID ROK_NASTUPU MZDA AVG_MZDA_1_ROK 201 20 1996 13000 202 1997 6000 122 50 1995 7900 5000 137 3600 141 3500 120 8000 133 3300

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 <window_clause> je: [ROW or RANGE] BETWEEN <start_expr> AND <end_expr> <start_expr> může být jedna z následujících UNBOUNDED PRECEDING CURRENT ROW <sql_expr> PRECEDING nebo FOLLOWING. <end_expr> může být jedna z následujících možností UNBOUNDED FOLLOWING CURRENT ROW <sql_expr> PRECEDING nebo FOLLOWING kde <sql_expr> hovořící o počtu řádků před či za aktuálním řádkem u ROW type okna.

Specifikace Window klauzule Do okna může nebo nemusí být zahrnut aktuální řádek dle hodnot v <start_expr> či <end_expr>. 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 <start_expr> a UNBOUNDED FOLLOWING pro <end_expr>. Jestliže konečným bodem je aktuální řádek, může být uvedena pouze syntaxe startovního bodu [ROW or RANGE] [<start_expr> PRECEDING or UNBOUNDED PRECEDING ] Pro analytické funkce s oknem typu ROW je obecná syntaxe : Function( ) OVER (PARTITION BY <expr1> ORDER BY <expr2,..> ROWS BETWEEN <start_expr> AND <end_expr>) nebo Function( ) OVER (PARTITON BY <expr1> ORDER BY <expr2,..> ROWS [<start_expr> PRECEDING or UNBOUNDED PRECEDING]

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 CURRENT ROW AND 3 FOLLOWING)) PRUMER_DANY_3_VYSSI FROM ZAMESTNANCI WHERE ODDELENI_ID IN (20, 30) ORDER BY ODDELENI_ID, MZDA; ODDELENI_ID ZAMESTNANEC_ID MZDA PRUMER_3_NIZSI PRUMER_DANY_3_VYSSI 20 202 6000 9500 201 13000 30 119 2500 2700 118 2600 2850 117 2800 2550 4950 116 2900 2633 5666 115 3100 2766 7050 114 11000 2933

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 (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_ID ZAMESTNANEC_ID MZDA O_10PCT_MENE O_10_50_PCT_VICE 20 202 6000 201 13000 1 30 119 2500 3 118 2600 2 117 2800 116 2900 115 3100 114 11000 5

Cvičení č. 3 - zadání Nad tabulkou LIDE ve schématu A_CLOVEK řešte pomocí analytických funkcí: 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. 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. 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. 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. 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.

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).

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; NAME PATH TOPMGR ISLEAF LEVEL King Steven /King King 1 Cambrault Gerald /King/Cambrault 2 Bates Elizabeth /King/Cambrault/Bates 3 Bloom Harrison /King/Cambrault/Bloom Fox Tayler /King/Cambrault/Fox Kumar Sundita /King/Cambrault/Kumar Ozer Lisa /King/Cambrault/Ozer Smith William /King/Cambrault/Smith De Haan Lex /King/De Haan Hunold Alexander /King/De Haan/Hunold Austin David /King/De Haan/Hunold/Austin 4

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