SQL - przypomnienie Podstawowa forma kwerendy SQL: select A1,..., Ak from R1,..., Rn where <warunek >; Odpowiada jej w algebrze relacji operacja π A1,...,Ak (σ <warunek> (R1 Rn))
SQL semantyka select R. A, T. B from R, T where <warunek >; Taka kwerendę można zrealizować następujaco: 1 Utwórż iloczyn kartezjański R T, 2 Wypisz pary atrybutów z tych wierszy R T, które spełniaja <warunek>. albo for all t R do for all t T do if t, t spełniają <warunek> then print t.a,t.b end if end for end for
SQL semantyka Jeśli jedna z tablic wymienionych po from jest pusta, to iloczyn kartezjański R T będzie pusty. W takim przypadku zapytanie nie zwróci żadnych krotek. Niech R(A, B), T (C, D) tabele takie, że T jest pusta. select A, B from R; zwróci nam tabelę R. select A, B from R, T ; nie zwróci żadnej krotki.
SQL semantyka Domyślnie tabele w bazie danych to zbiory. Nie można trzymać w jednej tabeli dwóch krotek o tych samych wartościach wszystkich atrybutów. W wyniku zapytania moga zostać zwrócone wielozbiory. Dzięki temu w nie tracimy informacji (nawet jeśli jest ona nam niepotrzebna). Przykład. Osoby(imie, nazwisko, id). Zapytanie select count ( imie ) from Osoby as o where o. imie= Ewa ; zwraca liczbę osób o imieniu Ewa.
SQL semantyka Jeśli chcemy usunać powtarzajace się krotki możemy użyć select d i s t i n c t imie, nazwisko from Osoby ; Taka operacja wymaga posortowania wyniku. Usunięcie powtórzeń może być kosztowniejsze niż obliczenie zapytania.
SQL operacje teoriomnogościowe Przy pomocy union, intersect, except możemy obliczyć sumę, część wspólna (przecięcie) oraz różnicę dwóch tabel. Operacje te domyślnie usuwaja duplikaty krotek! Aby zachować duplikaty trzeba użyć słowa kluczowego all.
SQL operacje teoriomnogościowe Rozważmy tabelę GRAF(poczatek, koniec) POCZATEK KONIEC 1 2 2 3 3 4 4 5
SQL operacje teoriomnogościowe Rozważmy select poczatek, koniec from g r a f union select poczatek, poczatek from g r a f ; Wyniki sa posortowane. Wyniki: POCZATEK KONIEC 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5
SQL operacje teoriomnogościowe Rozważmy select poczatek, koniec from g r a f union a l l select poczatek, poczatek from g r a f ; Wyniki: POCZATEK KONIEC 1 2 2 3 3 4 4 5 1 1 2 2 3 3 4 4 Zauważmy, że w tym przypadku wyniki sa nieposortowane.
SQL operacje teoriomnogościowe Zapytania select poczatek from g r a f ; select poczatek from g r a f union select poczatek from g r a f ; select poczatek from g r a f union a l l select poczatek from g r a f ; moga zwrócić inne wyniki!
SQL operacje teoriomnogościowe Oracle 11g stosuje minus zamiast except. Oracle 11g nie implementuje intersect all oraz minus all.
SQL złaczenia Operację łaczenia z algebry relacji możemy wykonać przy użyciu join. Iloczyn kartezjański dwóch tabel R T otrzymamy za pomoca R cross join T.
SQL złaczenia Jeśli chcemy ograniczyć krotki w złaczeniu do spełniajacych pewien warunek możemy napisać: Zapytanie: select from g r a f g join g r a f t on g. koniec = t. poczatek ; Wynik: POCZATEK KONIEC POCZATEK1 KONIEC1 1 2 2 3 2 3 3 4 3 4 4 5 Otrzymaliśmy tylko te krotki, które spełniaja warunek po on. Z grafów g i t zgineły krotki!
SQL złaczenia Możemy zachować wszystkie zaginione krotki. Zapytanie: select from g r a f g f u l l outer j oin g r a f t on g. koniec = t. poczatek ; Wynik: POCZATEK KONIEC POCZATEK1 KONIEC1 (null) (null) 1 2 1 2 2 3 2 3 3 4 3 4 4 5 4 5 (null) (null)
SQL złaczenia Możemy zachować zaginione (wiszace) krotki z grafu g. Zapytanie: select from g r a f g l e f t outer j oin g r a f t on g. koniec = t. poczatek ; Wynik: POCZATEK KONIEC POCZATEK1 KONIEC1 1 2 2 3 2 3 3 4 3 4 4 5 4 5 (null) (null)
SQL złaczenia Możemy zachować wiszace krotki z grafu t. Zapytanie: select from g r a f g r i g h t outer join g r a f t on g. koniec = t. poczatek ; Wynik: POCZATEK KONIEC POCZATEK1 KONIEC1 1 2 2 3 2 3 3 4 3 4 4 5 (null) (null) 1 2
SQL złaczenia Niech tabela graf posiada dwa wiersze (1, null) oraz (null, 2). Zapytanie select from g r a f g join g r a f t on g. koniec = t. poczatek ; nie zwróci żadnej krotki. Wartość porównania null = null nie jest zdefiniowana.
SQL podzapytania Po słowach from, where może wystapić nowe zapytanie. select poczatek, koniec from g r a f g where ( g. poczatek 2, g. koniec +2) in ( select from g r a f ) ; To zapytanie zwróci nam jedna krotkę (2, 3). Po where nie możemy użyć samej tabeli. Napisanie where ( g. poczatek 2, g. koniec +2) in ( g r a f ) byłoby niepoprawne składniowo (Oracle).
SQL podzapytania W warunkach wykorzystujacych relacje R i krotkę s możemy używać: 1 EXISTS R, 2 s in R, 3 s > ALL R, 4 s > ANY R, 5 s<> ALL R. Wyrażenia możemy poprzedzać negacja, np. NOT EXISTS R. Pewne wyrażenia sa równoważne: 1 s = ANY R jest równoważne s in R, 2 NOT s > ALL S jest równoważne s <= ANY R.
SQL podzapytania Jeśli wiemy, że zapytanie zwróci tylko jedna wartość, możemy użyć jego wyniku do porównania: where n = ( select numer from R, T where R. numer = T. i d ) Podobnie, możemy porównać całe krotki where ( n, k o l o r ) = ( select R. numer, T. k o l o r from R, T where R. numer = T. i d )
SQL podzapytania skorelowane Wyniki pewnych podzapytań zależa od aktualnie testowanych krotek na zewnatrz danego podzapytania. Wtedy trzeba obliczać je za każdym przypisaniem wartości tym krotkom. Przykład. Tabela Filmy(tytul, rok, dlugosc). select t y t u l from f i l m y s t a r y where rok < ANY ( select rok from f i l m y where t y t u l = s t a r y. t y t u l ) ;
SQL agregowanie W SQL możemy obliczać wartości dla wszystkich wierszy w tabeli. Dostępne funkcje: SUM(A), AVG(A), MIN(A), MAX(A), COUNT(*), COUNT(DISTINCT A). Ich argumetny moga być wyrażeniami, np. SUM(A 2). Przykład Filmy(tytul, rok, dlugosc). select count ( d i s t i n c t t y t u l ) from Filmy ; select sum( dlugosc ) from Filmy where rok =2010;
SQL agregowanie Jeśli chcemy obliczyć wartość funkcji agregujacej oddzielnie dla różnych grupi wyniku używamy group by. Przykład Filmy(tytul, rok, rezyser, dlugosc). select sum( dlugosc ) from Filmy group by rok ; select rok, rezyser, sum( dlugosc ) from Filmy group by rok, rezyser ;
SQL agregowanie Możemy też ograniczyć wynik zapytania używajac funkcji agregujacej: having. Przykład Filmy(tytul, rok, rezyser, dlugosc). Jeśli interesuje nas długość filmów, wyprodukowanych przez reżyserów, którzy zaczeli pracować po roku 2000 napiszemy: select rezyser, sum( dlugosc ) from Filmy group by rezyser having min ( rok ) >=2000; Albo sami reżyserzy: select rezyser from Filmy group by rezyser having min ( rok ) >=2000;
SQL perspektywy SQL daje nam możliwość tworzenia perspektyw. Perspektywy nie sa przechowywane jako oddzielne tabele w bazie danych. Możemy je interpretować jako skróty dla zapytań, które je definiuja - w zapytaniu perspektywa zamieniana jest na podzapytanie SQL. Możemy korzystać z perspektyw w zapytaniach jak z tabel ale ich wartość jest za każdym razem obliczalna. Zapewniaja lepsza izolację danych i czytelność zapytań. create view stopien_wierzcholka as select poczatek wierzcholek, count ( ) stopien from g r a f group by poczatek ;
SQL perspektywy W poprzednim przykładzie traciliśmy wierchołki o stopniu wychodzacym 0 ale raczej nie chcemy też, żeby obliczenie perspektywy trwało długo. create view stopien_wierzcholka as select poczatek wierzcholek, count ( ) stopien from g r a f group by poczatek union a l l select koniec wierzcholek, 0 stopien from g r a f where g r a f. koniec not in ( select poczatek from g r a f ) ;
SQL perspektywy Jeśli perspektywa jest utworzona z jednej tabeli (lub perspektywy) i wykorzystane w niej atrybuty można uzupełnić wartościami domyślnymi do pełnego wiersza wyjściowej tabeli do do perspektywy możemy wstawiać krotki. Wynikiem jest wtedy wstawienie krotek do wyjściowej tabeli. Usunięcie krotki z perspektywy (jeśli jest to możliwe) skutkuje usunięciem wszystkich pasujacych do niej krotek z tabeli.
SQL definiowanie relacji w zapytaniu Potrzebna nam relację możemy zdefiniować też przed właściwym zapytaniem. Służy do tego konstrukcja with R( A1,..., Ak ) as ( select.... ) select.... from R,... where.... ;
SQL definiowanie relacji w zapytaniu Rozważmy tabelę GRAF(poczatek, koniec) POCZATEK KONIEC 1 2 2 3 3 4 4 5
SQL definiowanie relacji w zapytaniu with GrafOdwrotny ( poczatek, koniec ) as ( select koniec, poczatek from g r a f ) select go. poczatek, g. koniec from g r a f g, GrafOdwrotny go where go. koniec = g. poczatek ; POCZATEK KONIEC 2 2 3 3 4 4 5 5
SQL zapytania rekurencyjne Chcemy obliczyć tranzytywne domknięcie relacji GRAF, czyli relację osiagalności. Obliczenie par wierzchołków (p,k) takich, że z p można osiagn ać k w dwóch krokach: select g1. poczatek, g2. koniec from g r a f g1, g r a f g2 where g1. koniec = g2. poczatek ; Obliczenie par wierzchołków (p,k) takich, że z p można osiagn ać k w trzech krokach: select g1. poczatek, g3. koniec from g r a f g1, g r a f g2, g r a f g3 where g1. koniec = g2. poczatek and g2. koniec = g3. poczatek ;
SQL zapytania rekurencyjne with t r a n s _ g r a f ( poczatek, koniec ) as ( select poczatek, koniec from g r a f union a l l select t1. poczatek, g. koniec from t r a n s _ g r a f t1, g r a f g where t1. koniec = g. poczatek ) select from t r a n s _ g r a f order by poczatek, koniec ; Uwaga. Relacja trans_graf pojawia się po from w jednym z członów sumy, która ja sama definiuje.
SQL zapytania rekurencyjne Wyniki zapytania: POCZATEK KONIEC 1 2 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5 4 5
SQL zapytania rekurencyjne Silnik bazy danych Oracle sprawdza czy obliczenie zapytania nie doprowadzi do nieskończonej pętli. W powyższym przykładzie zapytanie with t r a n s _ g r a f ( poczatek, koniec ) as ( select poczatek, koniec from g r a f union a l l select t1. poczatek, g. koniec from t r a n s _ g r a f t1, t r a n s _ g r a f t2 where t1. koniec = t2. poczatek ) select from t r a n s _ g r a f order by poczatek, koniec ; nie zwróciłoby wyniku.
SQL zapytania rekurencyjne Podobnie dołożenie krawędzi (1, 1) do grafu sprawia, że Oracle rozpoznaje pętle podczas obliczania odpowiedzi. Warto więc zastanowić się czy naprawdę potrzebujemy rekursji.
SQL funkcje analityczne Funkcje agregujace pozwalaja obliczyć wartość zależna od wszystkich (pogrupowanych) wierszy w odpowiedzi. Funkcje analityczne pozwalaja obliczać funkcje zależne tylko od części wyniku. Np. pozwalaja obliczać postępujac a sumę, N największych (najmniejszych) wartości, wyznaczać ranking, obliczać funkcje na podstawie danego rekordu i jego N sasiadów Funkcje analityczne wykonywane sa po instrukcjach join, where, group by, having a przed instrukcja order by.
SQL funkcje analityczne Składnia funkcji analitycznej: f u n c t i o n ( A2,..., Ak ) over ( < p a r t i t i o n by argument> <order by argument > <windowing clause >)
SQL funkcje analityczne partition by... dzieli wynik zapytania na części, dla których beda, oddzielnie, obliczane wartości funkcji, order by... definiuje porzadek w jakim będa podawane wiersze przy obliczaniu funkcji, nie musi być to porzadek wypisywania wyników, windowing-clause definiuje, od których wierszy z tabeli zależy wynik funkcji.
SQL funkcje analityczne Przykład. Osoby(imie, nazwisko, id). IMIE NAZWISKO ID Jan Kowalski 1 Ewa Kowalska 2 Marian Kowalski 3 Roman Kowalski 4 Ewa Kowalska 5 Chcemy obliczyć kolejność osób zgodna z imieniem.
SQL funkcje analityczne Chcemy obliczyć kolejność osób zgodna z imieniem. select imie, nazwisko, rank ( ) over ( order by imie ) as miejsce from osoby ; IMIE NAZWISKO MIEJSCE Ewa Kowalska 1 Ewa Kowalska 1 Jan Kowalski 3 Marian Kowalski 4 Roman Kowalski 5
SQL funkcje analityczne Chcemy obliczyć kolejność osób zgodna z imieniem. select imie, nazwisko, dense_rank ( ) over ( order by imie ) as miejsce from osoby ; IMIE NAZWISKO MIEJSCE Ewa Kowalska 1 Ewa Kowalska 1 Jan Kowalski 2 Marian Kowalski 3 Roman Kowalski 4
SQL funkcje analityczne Możemy skorzystać też z funkcji agregujacych. Beda obliczane dla każdego wiersza oddzielnie, nie tylko dla całej grupy. select imie, nazwisko, i d sum( i d ) over ( p a r t i t i o n by imie order by i d ) as suma from osoby ; IMIE NAZWISKO ID SUMA Ewa Kowalska 2 2 Ewa Kowalska 5 7 Jan Kowalski 1 1 Marian Kowalski 3 3 Roman Kowalski 4 4
SQL funkcje analityczne Porzadek generowania wyników może zostać zmieniony, przez dodanie na końcu zapytania polecenia order by. Nie zmienia to wartości funkcji analitycznej. select imie, nazwisko, i d sum( i d ) over ( p a r t i t i o n by imie order by i d ) as suma from osoby order by i d ; IMIE NAZWISKO ID SUMA Jan Kowalski 1 1 Ewa Kowalska 2 2 Marian Kowalski 3 3 Roman Kowalski 4 4 Ewa Kowalska 5 7
SQL funkcje analityczne Możemy modyfikować porzadek: asc, desc. Wartości null możemy ustawiać na końcu lub poczatku: nulls [first last]. Inne funkcje: ntile(n), percent_rank(), cume_dist() Jeśli chcemy tylko przypisać wierszom unikatowe numery możemy użyć funkcji row_number(). To pozwala łatwo znaleźć pierwszych N krotek. Jeśli chcemy powtarzalnych wyników musimy sortować po unikatowym kluczu.
SQL funkcje analityczne Przykład. Użycie row_number(). select imie, nazwisko, id, row_number ( ) over ( order by i d desc ) as rn from osoby ; IMIE NAZWISKO ID RN Ewa Kowalska 5 1 Roman Kowalski 4 2 Marian Kowalski 3 3 Ewa Kowalska 2 4 Jan Kowalski 1 5 Uwaga. Użycie rn w klauzuli where jest nielegalne - funkcje analityczne sa obliczane po where, group by, having a przed order by.
SQL funkcje analityczne Przykład. Użycie row_number(). Aaaaaby otrzymać wiersze z pewnego zakresu możemy zagnieździć zapytanie używajace row_number(). select imie, nazwisko, rn from ( select imie, nazwisko, id, row_number ( ) over ( order by i d desc ) as rn from osoby ) where 1< rn and rn < 5;
SQL funkcje analityczne Funkcje SUM, COUNT, AVG, MIN, MAX nie zależa od porzadku wierszy. Jeśli obliczenie zależy od porzadku generowania wierszy powinniśmy go podać w over (...) przez order by. Forma: order by expr [asc desc] nulls [first last]. Funkcje zależace od porzadku: LEAD, LAG, RANK, DENSE_RANK, ROW_NUMBER, FIRST, FIRST VALUE, LAST, LAST VALUE.
SQL funkcje analityczne first_value(sql-expr) oblicza wartość sql-expr na pierwszej krotce w grupie zdefiniowanej przez partition. select imie, nazwisko, id, i d f i r s t _ v a l u e ( i d ) over ( p a r t i t i o n by nazwisko order by nazwisko, imie, i d ) as d i f f from osoby ; IMIE NAZWISKO ID DIFF Ewa Kowalska 2 0 Ewa Kowalska 5 3 Jan Kowalski 1 0 Marian Kowalski 3 2 Roman Kowalski 4 3
SQL funkcje analityczne lead(sql-expr,offset, default) oblicza wartość sql-expr na krotce występujacej w grupie offset pozycji po aktualnej. select imie, nazwisko, id, i d + lead ( id,1, 10) over ( p a r t i t i o n by nazwisko order by nazwisko, imie, i d ) as sum from osoby ; IMIE NAZWISKO ID SUM Ewa Kowalska 2 7 Ewa Kowalska 5-5 Jan Kowalski 1 4 Marian Kowalski 3 7 Roman Kowalski 4-6 Wartość domyślna dla offset to 1. Jeśli dana krotka nie istnieje, to zostanie zwrócona wartość default.
SQL funkcje analityczne Funkcja analogiczna do first_value to last_value. Funkcja analogiczna do lead to lag(sql-expr, offset, default).
SQL funkcje analityczne select imie, nazwisko, id, sum( i d ) over ( order by nazwisko, imie, i d rows between 1 preceding and i d f o l l o w i n g ) as sum from osoby ; IMIE NAZWISKO ID SUM Ewa Kowalska 2 8 Ewa Kowalska 5 15 Jan Kowalski 1 9 Marian Kowalski 3 8 Roman Kowalski 4 7
SQL dygresja Czasem zamiast row_number() wystarczy użyć pseudokolumny Oracle rownum. Dla każdej tabeli i wyniku zapytania możemy posłużyć się rownum, która przechowuje kolejne numery wierszy tabeli (liczac od 1). select imie, nazwisko, rownum from osoby where rownum <4; IMIE NAZWISKO ROWNUM Jan Kowalski 1 Ewa Kowalska 2 Marian Kowalski 3
SQL dygresja select imie, nazwisko, rownum from osoby where rownum <4; zwraca tylko pierwsze trzy wiersze select imie, nazwisko, rownum from osoby where rownum >1; nie zwróci żadnego wiersza, bo rownum przypisuje pierwszemu wierszowi numer 1. Każdy kolejno testowany wiersz będzie miał domyślnie przypisany rownum = 1. Użycie rownum może wyłaczyć pewne optymalizacje w obliczaniu zapytań.
Koniec