ORACLE System Zarządzania Bazą Danych Oracle Oracle Advanced SQL wersja 1.0 Politechnika Śląska 2008
Raportowanie z wykorzystaniem fraz rollup, cube Frazy cube, rollup, grouping sets umożliwiają rozszerzoną specyfikację poziomów grupowania frazy group by standardu SQL. Zapytania wykorzystujące frazy cube, rollup, grouping sets dostarczają pojedynczego zbioru odpowiedzi, który odpowiada połączeniu (UNION ALL) danych pogrupowanych w różny sposób. Fraza rollup wylicza wartości podanych funkcji agregujących na różnych poziomach grupowania od najniższego do najwyższego. Fraza cube rozszerza działanie frazy rollup na wszystkie możliwe kombinacje poziomów agregacji. Funkcja grouping pozwala odróżnić informacje zwracane dzięki zastosowaniu fraz cube i rollup (dodatkowe podsumowania, grouping zwraca 1) od danych zwracanych dzięki zastosowaniu frazy group by (dane zwracane przez zapytanie standardu SQL, grouping zwraca 0). Dzięki zastosowaniu funkcji grouping możliwe jest również rozróżnienie wartości NULL zwracanych przez frazy cube i rollup (co wskazuje, że mamy do czynienia z określonym poziomem grupowania) od wartości NULL, które charakteryzują grupy danych. Funkcja grouping może być także wykorzystana w celu filtrowania otrzymanych rezultatów. W celu uniknięcia konieczności specyfikowania użycia funkcji grouping dla każdej z kolumn grupowania można wykorzystać funkcję grouping_id(<lista_kolumn_grupowania>) zwracającą pojedynczą wartość (liczbę) której reprezentacja bitowa określa jednoznacznie poziom grupowania. Wyrażenie grouping sets umożliwia jawną specyfikację żądanych poziomów agregacji, eliminując przetwarzanie pozostałych, zbędnych poziomów (co może mieć miejsce przy zastosowaniu frazy cube). Składnia SELECT [GROUPING( <kolumna_grupowania> ) ] GROUP BY ROLLUP( <lista_kolumn_grupowania> ) SELECT [GROUPING( <kolumna_grupowania> ) ] GROUP BY CUBE( <lista_kolumn_grupowania> ) np., SELECT GROUPING(channel_desc) AS Ch, GROUPING(calendar_month_desc) AS Mo, GROUPING(country_iso_code) AS Co GROUP BY ROLLUP(channels.channel_desc, calendar_month_desc, countries.country_iso_code) SELECT GROUPING(channel_desc) AS Ch, GROUPING(calendar_month_desc) AS Mo, GROUPING(country_iso_code) AS Co GROUP BY CUBE(channels.channel_desc, calendar_month_desc, countries.country_iso_code) Fraza: CUBE(a, b, c) odpowiada wyrażeniu: GROUPING SETS ((a, b, c), (a, b), (a, c), (b, c), (a), (b), (c), ()) 2
Raportowanie z wykorzystaniem funkcji analitycznych SQL Funkcje analityczne umożliwiają wyznaczenie m.in. pozycji (rankingów), kwantyli, udziałów procentowych wartości (średnich, sum) kroczących analizy szeregów czasowych znajdowanie pierwszych i ostatnich wartości w uporządkowanych grupach statystyk regresji liniowej Przykład. RANK i DENSE_RANK umożliwiają wyznaczenie pozycji elementu w grupie. Wskazanie frazy zapytania partycjonującego dane powoduje wyznaczenie rankingu dla każdego zdefiniowanego podzbioru danych. RANK ( ) OVER ( [<fraza zapytania partycjonującego dane>] order by ) DENSE_RANK ( ) OVER ( [<fraza zapytania partycjonującego dane>] order by ) np., RANK() OVER (ORDER BY SUM(amount_sold)) RANK() OVER (PARTITION BY calendar_month_desc ORDER BY SUM(amount_sold) Funkcje kroczącego okna pozwalają na m.in. na wyznaczenie wartości skumulowanych i średnich kroczących. gdzie np., {SUM AVG MAX MIN COUNT STDDEV VARIANCE FIRST_VALUE LAST_VALUE} ({<wyraŝenie_1> *}) OVER ([PARTITION BY wyraŝenie_2[,...]) ORDER BY wyraŝenie_3 [<fraza_sortowania>] [ASC DESC] [NULLS FIRST NULLS LAST] [,...] {ROWS RANGE} {BETWEEN {UNBOUNDED PRECEDING CURRENT ROW wyraŝenie {PRECEDING FOLLOWING}} AND { UNBOUNDED FOLLOWING CURRENT ROW wyraŝenie { PRECEDING FOLLOWING } } { UNBOUNDED PRECEDING CURRENT ROW wyraŝenie PRECEDING}} <wyrażenie_1> argumenty funkcji analitycznej (wartości numeryczne), <wyrażenie_2> określa sposób partycjonowania danych, <wyrażenie_3> określa sposób sortowania danych SUM(SUM(amount_sold)) OVER (PARTITION BY c.cust_id ORDER BY c.cust_id, t.calendar_quarter_desc ROWS UNBOUNDED PRECEDING) Jako argument funkcji analitycznej okna kroczącego należy podać funkcję agregującą (tak jak w podanym przykładzie). ROWS i RANGE definiują okno (zbiór danych) dla każdego z rekordów, dla którego liczona jest funkcja analityczna: ROWS określa okno poprzez podanie fizycznej liczby rekordów RANGE określa okno poprzez podanie logicznego zakresu Dla wyrażenie długości okna można użyć nst. konstrukcji: RANGE 10 PRECEDING ROWS 2 PRECEDING RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW (forma skrócona RANGE UNBOUNDED PRECEDING) 3
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING (forma skrócona RANGE UNBOUNDED FOLLOWING) RANGE BETWEEN INTERVAL '1' DAY PRECEDING AND INTERVAL '1' DAY FOLLOWING 4
Raportowanie z wykorzystaniem modeli SQL Fraza model wzbogaca SQL o właściwości charakterystyczne dla arkuszy kalkulacyjnych. Fraza ta, na podstawie wyników zapytania, umożliwia tworzenie wielowymiarowych tabel, do których możliwe jest zastosowanie formuł (zwanych regułami) wyznaczających żądane wartości. Wielowymiarowa tabela definiowana we frazie model powstaje w wyniku przypisania elementów wyniku zapytania do jednej z 3 grup: partycji, wymiarów lub miar. Partycja definiuje logiczne podzbiory danych (podobnie jak w zapytaniach wykorzystujących funkcje analityczne). Reguły frazy model są stosowane do każdej z partycji niezależnie. Wymiary definiują wielowymiarową tabelę i służą do identyfikacji komórek w ramach partycji. Domyślnie, kombinacja wszystkich wymiarów powinna wskazywać pojedynczą komórkę partycji. Miary przechowują wartości podlegające przetwarzaniu. Fraza model umożliwia specyfikację reguł przetwarzania (modyfikowania, tworzenia nowych) wartości miar określonych poprzez kolumny partycji i wymiarów. Schemat przetwarzania Zapytanie: select country, product, year, sum(sales) as sales,.. Definicja modelu specyfikacja grup modelu dla elementów wyniku country partycja product, year wymiary sales miara Definicja modelu specyfikacja reguł: sales[prod1, 2006] = sales[prod1, 2004] + sales[prod1, 2005] sales[prod2, 2006] = sales[prod2, 2004] + sales[prod2, 2005] Końcowy wynik zapytania, przy zastosowaniu reguł modelu: Country Product Year Sales Partycja Wymiar Wymiar Miara Poland Prod1 2004 1 Poland Prod1 2005 2 Poland Prod2 2004 3 Poland Prod2 2005 4 Canada Prod1 2004 5 Canada Prod1 2005 6 Canada Prod2 2004 7 Canada Prod2 2005 8 Poland Prod1 2006 3 Poland Prod2 2006 7 Canada Prod1 2006 11 Canada Prod2 2006 15 Podstawowe wyniki zapytania Wynik zastosowania reguł Fraza model umożliwia: adresowanie komórek z użyciem wartości wymiarów, np.: sales[product='prod1', year=2004] (można również użyć sales['prod1', 2004]), 5
specyfikację reguł operujących na danych, np.: sales[product='prod1', year=2006] = MAX(sales) [product='prod1', year between 2003 and 2005] modyfikację i/lub tworzenie nowych wartości miar (opcja może być specyfikowana dla każdej z reguł) o UPSERT opcja domyślna, tworzy wartości komórek, które nie istnieją w danych wejściowych a modyfikuje wartości komórek istniejących, o UPSERT ALL opcja UPSERT dla szerszego zakresu reguł o UPDATE tylko modyfikacja komórek istniejących stosowanie znaków wieloznacznych w odwoływaniu się do wymiarów: o ANY, IS ANY oznacza dowolną wartość wymiaru, np.: sales[any, 2006] = sales['prod1', 2005] dostęp do wartości wymiaru z użyciem funkcji CV() funkcję można użyć po prawej stronie reguły w celu uzyskania dostępu do wartości wymiaru komórki opisywanej po lewej stronie reguły; funkcja umożliwia tworzenie reguł o wyższym stopniu ogólności, np. 3 reguły sales[product='prod1', year=2006] = 1.2 * sales['prod1', 2005] sales[product='prod2', year=2006] = 1.2 * sales['prod2', 2005] sales[product='prod3', year=2006] = 1.2 * sales['prod3', 2005] można zastąpić regułą: sales[product in ('Prod1','Prod3','Prod3'), year=2006] = 1.2 * sales[cv(product), 2005] określenie kolejności przetwarzania danych w przypadku modyfikacji wartości może okazać się konieczne wymuszenie szczególnego porządku przetwarzania wartości wymiaru należy użyć opcji ORDER BY, np. sales[product IS ANY, year BETWEEN 2000 AND 2003] ORDER BY year = 1.05 * sales[cv(product), CV(year)-1] co zapewnia dostęp do wartości lat w porządku chronologicznym określenie automatycznego uporządkowania reguł od siebie zależnych (RULES AUTOMATIC ORDER) w przypadku następujących reguł, dwie ostatnie reguły będą przetworzone przed pierwszą: {sales[product='prod1', year=2001] = sales[product='prod1', year=2000] + sales[product='prod1', year=1999] sales[product='prod1', year=2000] = 50000, sales[product='prod1', year=1999] = 40000} iteracyjne przetwarzanie reguł do czasu osiągnięcia warunku końcowego, np.: MODEL DIMENSION BY ( ) MEASURES ( ) RULES ITERATE (<liczba_iteracji>) (<reguła>) oprócz ITERATE możliwe jest użycie frazy UNTIL, odwołanie się (tylko do odczytu) do innych modeli referencyjnych. Składnia MODEL [<globalne opcje referencji>] [<modele referencyjne>] [MAIN <nazwa-główna>] [PARTITION BY (<kolumny>)] DIMENSION BY (<kolumny >) MEASURES (<kolumny >) [<opcje referencji>] [RULES] <opcje reguł> (<reguła>, <reguła>,.., <reguła>) <globalne opcje referencji> ::= <opcje referencji> <ret-opt> <ret-opt> ::= RETURN {ALL UPDATED} ROWS <opcje referencji> ::= [IGNORE NAV [KEEP NAV] 6
[UNIQUE DIMENSION UNIQUE SINGLE REFERENCE] <opcje reguł> ::= [UPDATE UPSERT UPSERT ALL] [AUTOMATIC ORDER SEQUENTIAL ORDER] [ITERATE (<liczba>) [UNTIL <warunek]] <modele referencyjne> ::= REFERENCE ON <ref-name> ON (<zapytanie>) DIMENSION BY (<kolumny>) MEASURES (<kolumny >) <opcje referencji> np. gdzie: SELECT SUBSTR(country,1,20) country, SUBSTR(product,1,15) product, year, sales FROM sales_view WHERE country in ('Italy', 'Japan') MODEL RETURN UPDATED ROWS MAIN simple_model PARTITION BY (country) DIMENSION BY (product, year) MEASURES (sales) RULES (sales['bounce', 2001] = 1000, sales['bounce', 2002] = sales['bounce', 2001] + sales['bounce', 2000], sales['y Box', 2002] = sales['y Box', 2001]) ORDER BY country, product, year; CREATE VIEW sales_view AS SELECT country_name country, prod_name product, calendar_year year, SUM(amount_sold) sales, COUNT(amount_sold) cnt, MAX(calendar_year) KEEP (DENSE_RANK FIRST ORDER BY SUM(amount_sold) DESC) OVER (PARTITION BY country_name, prod_name) best_year, MAX(calendar_year) KEEP (DENSE_RANK LAST ORDER BY SUM(amount_sold) DESC) OVER (PARTITION BY country_name, prod_name) worst_year FROM sales, times, customers, countries, products WHERE sales.time_id = times.time_id AND sales.prod_id = products.prod_id AND sales.cust_id =customers.cust_id AND customers.country_id=countries.country_id GROUP BY country_name, prod_name, calendar_year; 7