DJ2 rekurze v SQL. slajdy k přednášce NDBI001. Jaroslav Pokorný

Podobné dokumenty
12. blok Pokročilé konstrukce SQL dotazů - část II

2. blok část B Základní syntaxe příkazů SELECT, INSERT, UPDATE, DELETE

RELAČNÍ DATABÁZOVÉ SYSTÉMY

Jazyk S Q L základy, příkazy pro práci s daty

B0M33BDT Technologie pro velká data. Supercvičení SQL, Python, Linux

Co bude výsledkem mého SELECTu? RNDr. David Gešvindr MVP: Data Platform MCSE: Data Platform MCSD: Windows Store MCT

Informační systémy 2008/2009. Radim Farana. Obsah. Jazyk SQL

Kurz Databáze. Obsah. Dotazy. Zpracování dat. Doc. Ing. Radim Farana, CSc.

Informační systémy 2008/2009. Radim Farana. Obsah. Dotazy přes více tabulek

KIV/ZIS - SQL dotazy. stáhnout soubor ZIS- 04_TestovaciDatabaze accdb. SQL dotazy. budeme probírat pouze SELECT

Maturitní témata z předmětu PROGRAMOVÉ VYBAVENÍ pro šk. rok 2012/2013

Databázové systémy. Cvičení 6: SQL

1. Relační databázový model

Vzorové příklady SQL. Tabulka: Kniha CREATE TABLE kniha (id INTEGER, název VARCHAR(50), PRIMARY KEY (id))

Úvod do databázových systémů

Databáze SQL SELECT. David Hoksza

Vkládání, aktualizace, mazání

PL/SQL. Jazyk SQL je jazykem deklarativním, který neobsahuje procedurální příkazy jako jsou cykly, podmínky, procedury, funkce, atd.

Operátory ROLLUP a CUBE

Úvod do databázových systémů

6. SQL složitější dotazy, QBE

Jazyk SQL slajdy k přednášce NDBI001

Obsah. SQL konstrukce select join Rekurze (rekurzivní with) Analytické funkce, group by Pivoting

SQL. strukturovaný dotazovací jazyk. Structured Query Language (SQL)

Jaký je rozdíl v definicicíh VARCHAR2(20 BYTE) a VARCHAR2(20 CHAR):

Databázové systémy I

Databázové systémy Tomáš Skopal

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

Úvod do databázových systémů

Zápisování dat do databáze

Návrh a tvorba WWW stránek 1/14. PHP a databáze

- sloupcové integritní omezení

2. přednáška. Databázový přístup k datům (SŘBD) Možnost počítání v dekadické aritmetice - potřeba přesných výpočtů, např.

ÚVOD DO DATABÁZÍ. Metodické listy pro předmět

Materializované pohledy

Informační systémy ve zdravotnictví. 10. cvičení

Platforma Java. Petr Krajča. Katedra informatiky Univerzita Palackého v Olomouci. Petr Krajča (UP) KMI/PJA: Seminář V. 27. říjen, / 15

Databázové a informační systémy

6. blok část B Vnořené dotazy

PRG036 Technologie XML

Databázové systémy II. KIV/DB2 LS 2007/2008. Zadání semestrální práce

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář

FAKULTA STAVEBNÍ STUDIJNÍ PROGRAM: GEODÉZIE A KARTOGRAFIE TYP PROGRAMU: MAGISTERSKÝ STUDIJNÍ OBOR: GEOMATIKA ÚVOD DO ZPRACOVÁNÍ PROSTOROVÝCH DAT

Marian Kamenický. Syntea software group a.s. marian.kamenicky. MFFUK Praha 2012/13

Dotazy v SQL. Výraz relační algebry R1( )[A1,A2,...,Aj] lze zapsat takto: SELECT A1,A2,...,Aj FROM R1 WHERE. Výraz (R1, R2... Rk)( )[A1,A2,...

XMW4 / IW4 Pokročilé SELECT dotazy. Štefan Pataky

KIV/ZIS cvičení 6. Tomáš Potužák

Dotazovací jazyk SQL I

KIV/ZIS cvičení 5. Tomáš Potužák

Databázové systémy. Datová integrita + základy relační algebry. 4.přednáška

4IT218 Databáze. 4IT218 Databáze

Úvod do databází. Modelování v řízení. Ing. Petr Kalčev

PG 9.5 novinky ve vývoji aplikací

8.2 Používání a tvorba databází

Tabulka fotbalové ligy

Databáze I. Přednáška 6

Databázové systémy. Dotazovací jazyk SQL - II

MS Access Dotazy SQL

Databázové systémy Cvičení 5.3

Databáze I. Přednáška 4

Osnova je orientační pro FIT, u FEKTu se dá předpokládat, že budou zohledněny předchozí znalosti studentů, kde většina s databází nikdy přímo

Dotazování v relačním modelu a SQL

Stručný obsah. část III Aktualizace dat Kapitola 10: Aktualizace databáze 257 Kapitola 11: Integrita dat 275 Kapitola 12: Zpracování transakcí 307

Úvod do databázových systémů 3. cvičení

Dotazovací jazyky I. Datová krychle. Soběslav Benda

Fakulta elektrotechniky a informatiky Databázové systémy 2. Leden 2010 souhrn. Červené dobře (nejspíš), modré možná

Gymnázium a Střední odborná škola, Rokycany, Mládežníků 1115

Jazyk SQL 2. Michal Valenta. Katedra softwarového inženýrství FIT České vysoké učení technické v Praze c M.Valenta, 2011 BI-DBS, ZS 2011/12

Materiál ke cvičením - SQL

Úvod do databázových systémů

5 Rekurze a zásobník. Rekurzivní volání metody

SQL v14. 4D Developer konference. 4D Developer conference 2015 Prague, CZ Celebrating 30 years

Databázové systémy Cvičení 5

Informační systémy ve zdravotnictví. 8. cvičení

Západočeská univerzita v Plzni Katedra informatiky a výpočetní techniky. 9. června krovacek@students.zcu.cz

InnoDB transakce, cizí klíče, neumí fulltext (a nebo už ano?) CSV v textovém souboru ve formátu hodnot oddělených čárkou

Obchodní akademie a Jazyková škola s právem státní jazykové zkoušky Jihlava

DATA CUBE. Mgr. Jiří Helmich

7. Integrita a bezpečnost dat v DBS

7. Integrita a bezpečnost dat v DBS

Databázové systémy I. 1. přednáška

Databáze. Velmi stručný a zjednodušený úvod do problematiky databází pro programátory v Pythonu. Bedřich Košata

Optimalizace dotazů a databázové transakce v Oracle

Uložené procedury Úvod ulehčit správu zabezpečení rychleji

Inovace a zkvalitnění výuky prostřednictvím ICT. Základní seznámení s MySQL Ing. Kotásek Jaroslav

6. blok část C Množinové operátory

KIV/ZIS - SELECT, opakování

Seznam účetních jednotek patřících do dílčího konsolidačního celku státu (seznam)

Základní přehled SQL příkazů

Univerzita Palackého v Olomouci Radek Janoštík (Univerzita Palackého v Olomouci) Základy programování 4 - C# 10.4.

Analýza a modelování dat. Přednáška 9

DATABÁZOVÉ SYSTÉMY MYSQL. Sestavil Mgr. Jan Kubrický. Distanční opora Poslední úprava:

Kapitola 4: SQL. Základní struktura

SII - Informatika. 1. Atribut relace, jehož hodnota jednoznačně určuje prvek v jiné relaci, se nazývá:

Informační systémy ve zdravotnictví. 6. cvičení

Popis souboru pro generování reportů *.report

SQL - trigger, Databázové modelování

Tvorba informačních systémů

Dobývání znalostí z databází. Databáze. datum jmeno prijmeni adresa_ulice adresa_mesto cislo_uctu platba zustatek

Využití XML v DB aplikacích

Transkript:

DJ2 rekurze v SQL slajdy k přednášce NDBI001 Jaroslav Pokorný 1

Obsah 1. Úvod 2. Tvorba rekurzívních dotazů 3. Počítaní v rekurzi 4. Rekurzívní vyhledávání 5. Logické hierarchie 6. Zastavení rekurze 7. Závěr SQL - rekurze 2

Rekurze v SQL Intuitivně: dotaz je rekurzívní, pokud je použit ve své vlastní definici tato vazba může být jak přímá, tak i přes několik tabulek Výhody: v jistých případech jediný efektivní způsob získání výsledku Nevýhody: často horší čitelnost a srozumitelnost SQL - rekurze 3

Kde použít rekurzi SQL efektivní pro jakákoliv data s hierarchickou strukturou vztahy ve stromových strukturách hledání v cyklických i acyklických grafech příklady z praxe hledání spojů v jízdních řádech organizační struktura firmy struktura výrobku složky v systému správy dokumentů atd... SQL - rekurze 4

Lze se obejít bez rekurze SQL před standardem SQL:99 neobsahoval možnost konstrukce rekurzívních dotazů neprocedurální řešení: s přidáním jistých grafových informací procedurální řešení: použití kurzorů, cyklů, Jiné: ORACLE: proprietární řešení + PL/SQL, ztráta efektivnosti a optimalizace kód není tak elegantní SQL - rekurze 5

Aplikace rekurze Pro procházení grafem získáváme: dosažitelnost D1. Najdi všechny podřízené dané osoby vyčíslitelnost cest D2. Pro daný výrobek najdi jeho celou strukturu se všemi jejími součástmi spojování cest D3. Pro daný výrobek proveď výčet a najdi počet všech součástek, potřebných pro jeho sestavení SQL - rekurze 6

Další výhody a nevýhody rekurze výhody: vše jedním dotazem lze využít velkou část výsledku nevýhody časté využití pouze malé části výsledku možnost zacyklení rekurze SQL - rekurze 7

Obsah 1. Úvod 2. Tvorba rekurzívních dotazů 3. Počítaní v rekurzi 4. Rekurzívní vyhledávání 5. Logické hierarchie 6. Zastavení rekurze 7. Závěr SQL - rekurze 8

Common Table Expression jde o zobecnění tabulkového výrazu z SQL:92 deklaruje se klíčovým slovem WITH slouží jako náhrada ve vnořených dotazech ze SELECT, INSERT, UPDATE, DELETE části za WITH jsou volány právě jednou WITH [RECURSIVE] CTE [, CTE] CTE ::=jméno_cte[(jméno_sl[,jméno_sl] )] AS (CTE_definice_dotazu) SQL - rekurze 10

Příspěvky(ID, fórum, otázka) Skládání agregací bez CTE D4: Najdi fórum s nevyšším počtem příspěvků SELECT COUNT(ID) AS počet, fórum FROM Příspěvky GROUP BY fórum HAVING COUNT(ID) = ( SELECT MAX(počet) FROM (SELECT COUNT(ID) AS počet, fórum FROM Příspěvky GROUP BY fórum) Pz.: Hledáme vlastně MAX(COUNT(...)) SQL - rekurze 11

Skládání agregací s CTE WITH Počet_příspěvků(počet, fórum) AS ( SELECT COUNT(ID), fórum) FROM Příspěvky GROUP BY fórum ) SELECT počet, fórum FROM Počet_příspěvků WHERE počet = (SELECT MAX(počet) FROM Počet_příspěvků) SQL - rekurze 12

Více CTE v jednom dotazu WITH Počet_příspěvků(počet, fórum) AS (SELECT COUNT(ID), fórum FROM Příspěvky GROUP BY fórum ), Max_počet_příspěvků(počet) AS (SELECT MAX(počet) FROM Počet_příspěvků) SELECT P1.* FROM Počet_příspěvků P1 INNER JOIN Max_počet_příspěvků P2 ON P1.počet = P2.počet Pz.: CTE fungují stejně jako odvozené tabulky (dané pomocí SELECT za FROM) SQL - rekurze 13

Přechod k rekurzi D5. č_zam jméno funkce č_nad 1 Novák ředitel NULL 2 Srb náměstek 1 3 Lomský vedoucí 2 4 Bor vedoucí 2 WITH Nadřízení(jméno, č_nad, č_zam) AS (SELECT jméno, č_nad, č_zam FROM Zaměstnanci WHERE funkce = 'vedoucí' ) SELECT * FROM Nadřízení jméno č_nad č_zam Lomský 2 3 SQL - rekurze Bor 2 4 14

Rekurzívní dotazy V CTE pro tabulku R se lze odkazovat na R vytvoří se dočasná tabulka (existuje pouze v době vyhodnocování dotazu) Tři časti WITH ukotvení (inicializační poddotaz) UNION ALL rekurzívní člen rekurze běží pokud není přidán žádný další záznam anebo není překročený limit rekurze (MAXRECURSION) pozor na zacyklení rekurzívního členu SELECT Vnější SELECT - dá výsledek dotazu SQL - rekurze 15

Příklad ukotvení: spouští se jednou rekurzívní člen: opakovaně spojení s minulým krokem výstup Co řešíme? WITH RECURSIVE Nadřízení(jméno, č_nad, č_zam) AS (SELECT jméno, č_nad, č_zam FROM Zaměstnanci WHERE jméno = 'Nový' UNION ALL SELECT Z.jméno, Z.č_nad, Z.č_zam FROM Zaměstnanci AS Z INNER JOIN Nadřízení AS N ON N.č_nad = Z.č_zam) SELECT * FROM Nadřízení jméno č_nad č_zam Nový 11 13 Ryba 6 11 Rak 5 6 Syka 4 5 Bor 2 4 Srb 1 2 Novák NULL 1 SQL - rekurze 16

D6.: Najdi všechny nadřízené Nového (včetně něho sama) Příklad ukotvení: spouští se jednou rekurzívní člen: opakovaně spojení s minulým krokem výstup WITH RECURSIVE Nadřízení(jméno, č_nad, č_zam) AS (SELECT jméno, č_nad, č_zam FROM Zaměstnanci WHERE jméno = 'Nový' UNION ALL SELECT Z.jméno, Z.č_nad, Z.č_zam FROM Zaměstnanci AS Z INNER JOIN Nadřízení AS N ON N.č_nad = Z.č_zam) SELECT * FROM Nadřízení jméno č_nad č_zam Nový 11 13 Ryba 6 11 Rak 5 6 Syka 4 5 Bor 2 4 Srb 1 2 Novák NULL 1 SQL - rekurze 17

Omezení rekurzívních dotazů V ukotvení se nelze odkazovat na CTE Rekurzívní část vždy samo-odkazuje na CTE SQL:99 podporuje pouze "lineární" rekurzi: každé FROM má nejvýše jeden odkaz na rekurzívně definovanou relaci. Rekurzívní část nemůže obsahovat SELECT DISTINCT GROUP BY HAVING skalární agregace TOP OUTER JOIN každý sloupec rekurzívního poddotazu musí být typově kompatibilní s příslušným sloupcem v inicializačním poddotazu používá se přetypování CAST SQL - rekurze 18

Obsah 1. Úvod 2. Tvorba rekurzívních dotazů 3. Počítaní v rekurzi 4. Rekurzívní vyhledávání 5. Logické hierarchie 6. Zastavení rekurze 7. Závěr SQL - rekurze 19

Počítaní v rekurzi D7. Jaké součástky (včetně počtu) jsou potřeba pro výrobu křídla křídlo 5 1 1 100 vzpěra křidélko podvozek 10 5 nýt 8 4 2 3 pant SQL - rekurze 20

Počítaní v rekurzi zjednodušené uložení v DB (relace Komponenty) s počtem jednotlivých součástek v daném dílu Díl ČástDílu Množství křídlo vzpěra 5 křídlo křidélko 1 křídlo podvozek 1 křídlo nýt 100 vzpěra nýt 10 křidélko pant 2 křidélko nýt 5 podvozek pant 3 podvozek nýt 8 pant nýt 4 SQL - rekurze 21

Počítaní v rekurzi dotazy D8. Kolik nýtů je použito celkem na výrobu jednoho křídla? D9. Seznam všech součástek včetně počtu potřebných na výrobu jednoho křídla? SQL - rekurze 22

Počítaní v rekurzi řešení Na co nesmíme zapomenout? základem je použití rekurze (průchod grafem) musíme sečíst počet nýtů v jednotlivých součástkách a zároveň musíme uvažovat počty jednotlivých součástek SQL - rekurze 23

Počítaní v rekurzi D8 CTE výsledek WITH RECURSIVE ČástiKřídla(ČástDílu, Množství) AS [inicializační (( SELECT ČástDílu, Množství poddotaz] FROM Komponenty WHERE Díl = křídlo ) UNION ALL ( SELECT k.částdílu, č.množství [rekurzívní poddotaz] * k.množství FROM ČástiKřídla č, Komponenty k WHERE č.částdílu = k.díl )); ČástDílu Množství vzpěra 5 přímé použití křidélko 1 podvozek 1 nýt 100 nýt 50 z vzpěry pant 2 z křidélka nýt 5 z křidélka pant 3 z podvozku nýt 8 z podvozku nýt 8 z pantu křidélka nýt 12 z pantu podvozku SQL - rekurze 24

Počítaní v rekurzi D8 a nakonec sečteme jednotlivý počty WITH RECURSIVE ČástiKřídla(ČástDílu, Množství) AS (( SELECT ČástDílu, Množství FROM Komponenty WHERE Díl = křídlo ) UNION ALL ( SELECT k.částdílu, č.množství * K.Množství FROM ČástiKřídla č, Komponenty k WHERE č.částdílu = k.díl )) SELECT sum(množství) AS Množství FROM ČástiKřídla WHERE ČástDílu = nýt ; Výsledek Množství 183 SQL - rekurze 25

Počítaní v rekurzi D9 Pro řešení D9 stačí změnit finální dotaz WITH RECURSIVE ČástiKřídla(ČástDílu, Množství) AS (( SELECT ČástDílu, Množství FROM Komponenty WHERE Díl = křídlo ) UNION ALL ( SELECT K.ČástDílu, Č.Množství * K.Množství FROM ČástiKřídla Č, Komponenty K WHERE Č.ČástDílu = K.Díl )) SELECT ČástDílu, sum(množství) AS Množství FROM ČástiKřídla GROUP BY ČástDílu; Výsledek ČástDílu Množství vzpěra 5 křidélko 1 podvozek 1 pant 5 nýt 183 SQL - rekurze 26

Syntaxe průchodu stromů v Oracle 9i SELECT sloupce FROM tabulka [WHERE podmínka3] START WITH podmínka1 CONNECT BY podmínka2 [ORDER BY ] Řádky vyhovující podmínce ve START WITH jsou považovány za kořenové řádky na první úrovni vnoření Pro každý řádek na úrovni i se rekurzivně hledají přímí potomci vyhovující podmínce v klauzuli CONNECT BY na úrovni i+1 Řádek předka se v podmínce označuje klíčovým slovem PRIOR SQL - rekurze 27

Syntaxe průchodu stromů v Oracle 9i Na závěr jsou odstraněny řádky nevyhovující podmínce ve WHERE Pokud není definováno třídění, odpovídá pořadí průchodu pre-order Každý řádek obsahuje pseudosloupec LEVEL, obsahující úroveň řádku v hierarchii SQL - rekurze 28

Zam(č_zam, jméno, vedoucí) Oracle 9i vs. SQL:99 vkládá mezery v počtu 2*Level Oracle 9i: SELECT LPAD(, 2*Level) jméno jméno, Level FROM Zam START WITH vedoucí IS NULL CONNECT BY vedoucí = PRIOR č_zam; SQL:99 WITH RECURSIVE Zam1 AS ( SELECT x.jméno AS jméno, 0 AS Level FROM Zam x WHERE vedoucí IS NULL UNION ALL SELECT y.jméno, Level+1 FROM Zam y JOIN Zam1 ON y.vedoucí = Zam1.č_zam) SELECT * FROM Zam1; SQL - rekurze 29

Oracle 9i vs. SQL:99 Efekt funkce LPAD Data Novák Srb Lomský Bor SQL - rekurze 30

Obsah 1. Úvod 2. Tvorba rekurzívních dotazů 3. Počítaní v rekurzi 4. Rekurzívní vyhledávání 5. Logické hierarchie 6. Zastavení rekurze 7. Závěr SQL - rekurze 31

Rekurzívní vyhledávání Snaha nalézt nejlepší řešení na základě jistých kritérii daného problému. Příklad: uvažujme letištní systém odletů a klienta, který by rád odcestoval ze San Francisca do New Yorku za co nejnižší cenu SQL - rekurze 32

Rekurzívní vyhledávání příklad letová mapa : SQL - rekurze 33

Rekurzívní vyhledávání příklad některé možnosti letu: SQL - rekurze 34

Rekurzívní vyhledávání příklad definice tabulky Lety číslo_l start cíl cena xxx01 SF CHG 275 xxx02 SF DLS 300 D10. Najdi pro San Francisko trasu do New Yorku za nejnižší cenu. Problém: jelikož mapa není acyklická, musíme vyřešit konec rekurze SQL - rekurze 35

Rekurzívní vyhledávání 1. řešení Dočasnou tabulku použitou v CTE nazveme Výlety jako ukotvení zvolíme poddotaz, který najde všechna města, do kterých se klient dostane ze San Francisca přímo rekurzívní poddotaz bude hledat města, kam se klient dostane z již dosažených měst SQL - rekurze 36

Rekurzívní vyhledávání 1. řešení WITH RECURSIVE Výlety (cíl, trasa, celková_cena) AS ((SELECT cíl, cíl, cena FROM Lety WHERE start = 'SF' ) UNION ALL (SELECT l.cíl v.trasa ',' l.cíl, v.celková_cena + l.cena FROM Výlety v, Lety l WHERE v.cíl = l.start)) SELECT trasa, celková_cena FROM výlety WHERE cíl = 'NY'; Kde je chyba? - do sloupce trasa vkládáme stále větší výraz - zacyklení SQL - rekurze 37

Rekurzívní vyhledávání 1. řešení + oprava porušení pravidla, že hodnota v sloupci rekurzívního pododotazu nesmí být delší v odpovídajícím sloupci inicializačního poddotazu (ukotvení) Řešení: změníme datový typ u obou poddotazů (inicializační i rekurzívní) na VARCHAR(50) k tomu slouží CAST výraz funkce CAST CAST (výraz AS typ_dat) Příklady: CAST (c1 + c2 AS Decimal(8,2)) CAST (jméno adresa AS Varchar(255)) string delší je doplněn mezerami kratší se uřízne a vrátí upozornění SQL - rekurze 38

Rekurzívní vyhledávání 1. řešení + oprava problém zacyklení Řešení: nebudeme brát v úvahu lety z počátku, tedy ze San Francisca nebudeme brát v úvahu lety z cíle, tedy z New Yorku a zajímají nás pouze lety, které mají maximálně 3 úseky SQL - rekurze 39

Rekurzívní vyhledávání finální řešení WITH RECURSIVE Výlety (cíl, trasa, #úsek, celková_cena) AS ((SELECT cíl, CAST(cíl AS Varchar(50)), 1, cena FROM Lety WHERE start = 'SF' UNION ALL (SELECT l.cíl, CAST(v.trasa ',' l.cíl AS Varchar(50)), v. #úsek + 1, v.celková_cena + l.cena FROM Výlety v, Lety l WHERE v.cíl = l.start AND l.cíl <> 'SF' AND l.start <> 'NY' AND v. #úsek < 4)) SELECT trasa, celková_cena FROM Výlety Výsledek trasa celková_cena DLS, NY 525 CHG,NY 525 WHERE cíl = 'NY ' AND celková_cena=(select min(celková_cena) FROM Výlety WHERE cíl='ny'); SQL - rekurze 40

Obsah 1. Úvod 2. Tvorba rekurzívních dotazů 3. Počítaní v rekurzi 4. Rekurzívní vyhledávání 5. Logické hierarchie 6. Zastavení rekurze 7. Závěr SQL - rekurze 41

Klasifikace hierarchií podle grafových vlastností Konvergentní Divergentní Rekurzívní podle vyváženosti Vyvážené všecky listy na stejné úrovni na každé úrovni jiné objekty (např. geografická struktura) Nevyvážené listy na různých úrovních jednotné objekty (např. organizační struktura) Problém: reprezentace pomocí relací SQL - rekurze 42

Divergentní hierarchie každý uzel kromě kořene má právě jednoho rodiče Př.: geografické hierarchie země, stát, město, ulice implementace Hrana (PKEY, KEYO) Primární klíč KEYO Tabulka s referenční integritou PKEY KEYO SQL - rekurze 43

Konvergentní hierarchie Každý objekt může mít libovolně předků a potomků Př.: Oddělení firmy Třeba definovat výsledky dotazu D11. Kolik potomků má AAA? 6, 7, 8? implementace tabulka objektů tabulka vztahů SQL - rekurze 44

Rekurzívní hierarchie jako konvergentní Navíc: rodič může být potomkem sebe sama (přímo nebo nepřímo) Příklad: nadřízeny-podřízený vs. vedoucí grantu a ředitel jako řešitel způsobují zacyklení v praxi je její použití většinou chybné implementace jako konvergentní (obyčejně) SQL - rekurze 45

Obsah 1. Úvod 2. Tvorba rekurzívních dotazů 3. Počítaní v rekurzi 4. Rekurzívní vyhledávání 5. Logické hierarchie 6. Zastavení rekurze 7. Závěr SQL - rekurze 46

Zastaveni rekurze Jak odstranit zacyklení v rekurzívních hierarchiích? Možnosti zastavení DB Server V MS SQL 2005 po dosažení hodnoty MAXRECURSION (default 100) po dosáhnutí n-té úrovně pamatovat si cestu a vynechat navštívené uzly SQL - rekurze 47

Problém rekurzívní hierarchie Tabulka RH PKEY AAA AAA CKEY BBB CCC AAA BBB CCC DDD AAA CCC DDD EEE EEE FFF DDD DDD AAA FFF GGG DDD EEE FFF GGG D12. Najdi potomky AAA do úrovně 4 SQL - rekurze 48

Zastavení po dosažení n-té úrovně (atribut LVL) WITH RECURSIVE RODIČ(CKEY, LVL) AS (SELECT DISTINCT PKEY, 0 FROM RH WHERE PKEY = 'AAA' UNION ALL SELECT T.CKEY, R.LVL+1 FROM RH H,RODIČ R WHERE R.CKEY = H.PKEY AND R.LVL + 1 < 4 ) SELECT CKEY, LVL FROM RODIČ; N = 4 co s duplicitami ve výsledku? SQL - rekurze 49

Vynechání duplicit (pomocí 2 CTE) WITH RECURSIVE RODIČ(CKEY, LVL) AS (SELECT DISTINCT PKEY, 0 FROM RH WHERE PKEY = 'AAA' UNION ALL SELECT H.CKEY, R.LVL+1 FROM RH H, RODIČ R WHERE R.CKEY = H.PKEY AND R.LVL + 1 <4 ), BEZ_DUPL(CKEY, LVL, NUM) AS (SELECT CKEY, MIN(LVL), COUNT(*) FROM RODIČ GROUP BY CKEY) SELECT CKEY, LVL, NUM FROM BEZ_DUPL SQL - rekurze 50

Ignorování již navštívených WITH RODIČ (CKEY, LVL, CESTA) AS (SELECT DISTINCT PKEY, 0, VARCHAR(PKEY, 20) ) UNION ALL FROM RH WHERE PKEY = AAA SELECT H.CKEY, R.LVL + 1, R.CESTA > H.CKEY FROM RH H, RODIČ R WHERE R.CKEY = H.PKEY AND LOCATE(H.CKEY >, R.CESTA) = 0 SELECT CKEY, LVL, CESTA FROM RODIČ; dá pozici vzoru v řetězci Výsledek CKEY LVL CESTA AAA 0 AAA BBB 1 AAA>BBB CCC 1 AAA>CCC DDD 1 AAA>DDD EEE 2 AAA>CCC>EEE EEE 2 AAA>DDD>EEE FFF 2 AAA>DDD>FFF GGG 3 AAA>DDD>FFF>GGG SQL - rekurze 51

Zásobník vs. rekurze Problém: jak efektivně implementovat rekurzi opakování spojení může vést k tomu, že se věci počítají opakovaně Rekurzi lze simulovat také pomocí zásobníku Zásobníkový model je rychlejší než CTE Dá se použít jen pro dotazovaní na hierarchická data SQL - rekurze 52

Vozidla(Id, rodičid, jméno) Příklad Id rodičid jméno 1 NULL ALL 2 1 moře 3 1 země 4 1 vzduch 5 2 ponorka 6 2 člun 7 3 auto 8 3 dvoukolá 9 3 kamión 10 4 raketa 11 4 letadlo 12 8 motocykl 13 8 bicykl SQL - rekurze 53

Příklad ALL moře země vzduch ponorka člun auto dvoukolá kamión raketa letadlo motocykl bicykl SQL - rekurze 54

Předchůdci bez rekurze (1) Dá se rekurze odstranit? ANO, pomocí zásobníku. Do tabulky přidáme 2 nové sloupce: P_hranice a L_hranice Jejich hodnoty vycházejí z očíslování, které vznikne průchodem stromu, SQL - rekurze 55

Předchůdci bez rekurze (2) Tabulku naplníme daty, pro nové sloupce UPDATE Vozidla SET L_hranice = 1, P_hranice = 26 WHERE ID = 1 UPDATE Vozidla SET L_hranice = 2, P_hranice = 7 WHERE ID = 2 UPDATE Vozidla SET L_hranice = 12, P_hranice = 13 WHERE ID = 12 UPDATE Vozidla SET L_hranice = 14, P_hranice = 14 WHERE ID = 13 SQL - rekurze 56

Předchůdci - bez rekurze (3) ALL 1,26 moře 2,7 země 8,19 20,25 vzduch ponorka člun auto dvoukolá kamión raketa letadlo 3,4 5,6 9,10 11,16 17,18 21,22 23,24 motocykl bicykl 12,13 14,15 SQL - rekurze 57

Příklad Id rodičid jméno L_hranice P_hranice 1 NULL ALL 1 26 2 1 moře 2 7 3 1 země 8 19 4 1 vzduch 20 25 5 2 ponorka 3 4 6 2 člun 5 6 7 3 auto 9 10 8 3 dvoukolá 11 16 9 3 kamión 17 18 10 4 raketa 21 22 11 4 letadlo 23 24 12 8 motocykl 12 13 13 8 bicykl 14 15 SQL - rekurze 58

Předchůdci - bez rekurze (4) Dotaz na předchůdce motocyklu využije intervalů. SELECT * FROM Vozidla WHERE P_hranice > 12 AND L_hranice < 13 SQL - rekurze 59

Příklad Id rodičid jméno L_hranice P_hranice 1 NULL ALL 1 26 2 1 moře 2 7 3 1 země 8 19 4 1 vzduch 20 25 5 2 ponorka 3 4 6 2 člun 5 6 7 3 auto 9 10 8 3 dvoukolá 11 16 9 3 kamión 17 18 10 4 raketa 21 22 11 4 letadlo 23 24 12 8 motocykl 12 13 13 8 bicykl 14 15 SQL - rekurze 60