Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Co to te CTE?

334 views

Published on

O co chodzi z rekurencyjnym CTE, jak zrobić PIVOT i co to GROUPING SETS?

Published in: Education
  • Be the first to comment

Co to te CTE?

  1. 1. Co to te CTE? I jak zrobić PIVOT? (oraz słów kilka o GROUPING SETS) 90. Spotkanie PLSSUG Warszawa, 08.10.2015
  2. 2. O czym będzie? • Co to CTE, a przede wszystkim jak działa rekurencja w CTE? • Jak obracać dane, czyli PIVOT i UNPIVOT na kilka sposobów • Grupowanie wielopoziomowe, czyli GROUPING SETS
  3. 3. O mnie Bartosz Ratajczyk programista baz danych (i aplikacji) czasem też administrator trener T-SQL, ETL, C#, PHP, JS, SAS 4GL http://bartekr.net | b.ratajczyk@gmail.com MCTS SQL Server 2008, MCSA SQL Server 2012, MCT
  4. 4. CTE Czyli Common Table Expression
  5. 5. Table expressions Nazwane zapytania, które możemy traktować tak samo jak tabele Nieutrwalone Utrwalone Derived table View Common Table Expression Table Valued Function
  6. 6. Jak wygląda CTE? -- pokaż sprzedaż pracowników w danym miesiącu ;WITH Dane AS ( SELECT Pracownik = p.nazwa, Produkt = pr.nazwa, RokMiesiac = YEAR(s.data_sprzedazy) * 100 + MONTH(s.data_sprzedazy), s.ilosc, s.wartosc FROM Sprzedaz s INNER JOIN Pracownik p ON p.id = s.pracownik_id INNER JOIN Produkt pr ON pr.id = s.produkt_id ) SELECT * FROM Dane
  7. 7. CTE z nazwami kolumn -- pokaż sprzedaż pracowników w danym miesiącu ;WITH Dane (Pracownik, Produkt, RokMiesiąc, Ilość, Wartość) AS ( SELECT Pracownik = p.nazwa, Produkt = pr.nazwa, RokMiesiac = YEAR(s.data_sprzedazy) * 100 + MONTH(s.data_sprzedazy), s.ilosc, s.wartosc FROM Sprzedaz s INNER JOIN Pracownik p ON p.id = s.pracownik_id INNER JOIN Produkt pr ON pr.id = s.produkt_id ) SELECT * FROM Dane
  8. 8. A ta rekurencja? ;WITH Poziomy AS ( SELECT <kolumny> FROM Pracownik p WHERE przelozony_id IS NULL UNION ALL SELECT <kolumny> FROM Pracownik p INNER JOIN Poziomy po ON po.pracownik_id = p.przelozony_id ) SELECT * FROM Poziomy
  9. 9. Rekurencja • Rekurencja w programowaniu: funkcja wywołuje samą siebie • Rekurencja w SQL: zapytanie wywołuje samo siebie Różnica między iteracją a rekurencją? Iteracja: 55 = 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 Rekurencja: 55 = 10 + (Suma liczb od 1 do 9) 55 = 10 + 9 + (Suma liczb od 1 do 8) 55 = 10 + (9 + (8 + (7 + (6 + (5 + (4 + (3 + (2 + (1)))))))))
  10. 10. DEMO
  11. 11. Plan zapytania rekurencyjnego CTE
  12. 12. Ma to jakieś ograniczenia albo wady? • CTE vs funkcja (32 poziomy) • MAXRECURSION X vs MAXRECURSION 0 • Widoczność tylko dla następnego zapytania • Trudniej testować niż derived tables • Każde odwołanie do CTE to jego wywołanie od zera (nie dotyczy rekurencji)
  13. 13. Obracanie danych Czyli PIVOT, UNPIVOT i inne konstrukcje
  14. 14. Jak wygląda polecenie PIVOT (i dlaczego tak?) SELECT Pracownik, Produkt, [201401], [201402], [201403], [201404], [201405], [201406], [201407], [201408], [201409], [201410], [201411], [201412] FROM Dane PIVOT ( SUM(ilosc) FOR RokMiesiac IN ( [201401], [201402], [201403], [201404], [201405], [201406], [201407], [201408], [201409], [201410], [201411], [201412] ) ) p
  15. 15. No ale dlaczego tak? • Jaich informacji potrzebujemy do obrócenia danych z wierszy na kolumny: • Po czym grupujemy? • Z której kolumny bierzemy atrybuty? • Które wartości nas interesują? • I jak je zliczać? A jak to przełożyć na kod – za chwilę
  16. 16. DEMO
  17. 17. To całkiem niezłe, ale ma ograniczenia • Tylko jedna funkcja agregująca w konstrukcji PIVOT • Muszę znać nazwy kolumn i podać je wprost Zgadza się, ale można to obejść
  18. 18. DEMO
  19. 19. To teraz w drugą stronę – z kolumn na wiersze SELECT Pracownik, Produkt, RokMiesiac, Wartosc FROM SprzedazPivot UNPIVOT ( Wartosc FOR RokMiesiac IN ( [201401], [201402], [201403], [201404], [201405], [201406], [201407], [201408], [201409], [201410], [201411], [201412] ) ) u
  20. 20. To znowu – dlaczego tak? • Jakich informacji potrzebujemy do zmiany kolumn na wiersze: • Które kolumny mają trafić jako wiersze? • Jak się ma nazywać kolumna, która będzie trzymała nazwy kolumn? • Jak ma się nazywać kolumna z wartościami z tych kolumn?
  21. 21. DEMO
  22. 22. Ten UNPIVOT tez ma wady • Też muszę podać nazwy tych wszystkich kolumn? Tak, ale wiesz już jak to obejść • Nie da się obrócić więcej niż jednego zestawu kolumn Ale na to też jest sposób
  23. 23. DEMO
  24. 24. GROUPING SETS Czyli grupujemy wielopoziomowo
  25. 25. Co to GROUPING SET? • To po prostu zestaw wyrażeń, po których grupujemy Czyli pisząc tak: GROUP BY Produkt, Rok, Miesiac, Dzien Możemy napisać tak: GROUP BY GROUPING SETS ( (Produkt, Rok, Miesiac, Dzien) ) (ale wyjdzie dłużej)
  26. 26. No rewelacja, a daje to coś więcej? • Oczywiście – możemy podać kilka zestawów na raz GROUP BY GROUPING SETS ( (Produkt, Rok, Miesiac, Dzien), (Produkt, Rok), (Produkt, Rok, Miesiac), ()-- <-- TOTAL )
  27. 27. DEMO
  28. 28. GROUPING() i GROUPING_ID() • GROUPING() sprawdza, czy rekord pochodzi z grupowania (1) czy to rekord źródłowy (0) SELECT GROUPING(Produkt) • GROUPING_ID() zwraca maskę bitową kolumn, które nie zostały użyte w grupowaniu SELECT GROUPING_ID(Produkt, Rok, Miesiac, Dzien)
  29. 29. CUBE i ROLLUP • Skracają pisanie wszystkich kombinacji GROUPING SETS • CUBE tworzy zbiór wszystkich możliwych kombinacji kolumn (2^N) • ROLLUP traktuje kolejne kolumny jako hierarchię (N + 1(TOTAL)) • Obowiązująca składnia: • GROUP BY ROLLUP (<kolumny>) • GROUP BY CUBE (<kolumny>) • Wycofywana składnia: • GROUP BY <kolumny> WITH ROLLUP • GROUP BY <kolumny> WITH CUBE
  30. 30. Pytania?

×