Operator przestawny w SQL Server konwertuje każdy wiersz w zagregowanym zestawie wyników na odpowiednie kolumny w zestawie wyjściowym. Operator przestawny jest szczególnie przydatny przy pisaniu zapytań z tabelami krzyżowymi.
Przyjrzyjmy się, jak to działa w praktyce.
Przygotowywanie danych
Najpierw utwórzmy kilka fikcyjnych danych, których będziemy mogli użyć do zaimplementowania operatora przestawnego.
CREATE DATABASE schooldb
CREATE TABLE student
(
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
gender VARCHAR(50) NOT NULL,
DOB datetime NOT NULL,
total_score INT NOT NULL,
city VARCHAR(50) NOT NULL
)
INSERT INTO student
VALUES (1, 'Jolly', 'Female', '12-JUN-1989', 500, 'London'),
(2, 'Jon', 'Male', '02-FEB-1974', 545, 'Manchester'),
(3, 'Sara', 'Female', '07-MAR-1988', 600, 'Leeds'),
(4, 'Laura', 'Female', '22-DEC-1981', 400, 'Liverpool'),
(5, 'Alan', 'Male', '29-JUL-1993', 500, 'London'),
(6, 'Kate', 'Female', '03-JAN-1985', 500, 'Liverpool'),
(7, 'Joseph', 'Male', '09-APR-1982', 643, 'London'),
(8, 'Mice', 'Male', '16-AUG-1974', 543, 'Liverpool'),
(9, 'Wise', 'Male', '11-NOV-1987', 499, 'Manchester'),
(10, 'Elis', 'Female', '28-OCT-1990', 400, 'Leeds');
Jak działa operator przestawny?
Standardowym sposobem grupowania danych SQL jest użycie klauzuli Group By. Utwórzmy zapytanie, które obliczy średnią wartości w kolumnie total_score tabeli uczniów, pogrupowanych według miasta.
USE schooldb
SELECT
city,
AVG(total_score) as Avg_Score
FROM
student
GROUP BY
city
Daje to następujący wynik:
[identyfikator tabeli=25 /]
A co, jeśli chcemy otrzymać zestaw wyników, w którym nazwy miast są wyświetlane w kolumnach, w których każda kolumna zawiera średnią wartość total_score uczniów należących do tego miasta? Coś takiego:
[identyfikator tabeli=26 /]
Tutaj przydaje się operator obrotu.
Wybieranie danych podstawowych
Pierwszym krokiem podczas korzystania z operatora przestawnego jest wybranie danych bazowych, na których będzie opierał się operator przestawny. Chcemy pogrupować nasze dane według miasta i znaleźć średnią całkowitego wyniku uczniów należących do tego miasta. Dlatego musimy napisać prostą instrukcję SELECT, która wybiera miasto i całkowity_wynik.
SELECT
city,
total_score
FROM
student
Tworzenie tymczasowego zbioru danych
Teraz najlepiej byłoby, gdybyśmy mogli bezpośrednio zastosować operator przestawny na danych bazowych, które stworzyliśmy w poprzedniej sekcji, ale niestety nie możemy. Aby operator przestawny działał, musimy utworzyć wyrażenie wyceniane w tabeli, do którego możemy zastosować operator przestawny. Mamy tu do wyboru różne opcje; moglibyśmy użyć tabel pochodnych, wspólnych wyrażeń tabelowych (CTE) lub nawet stworzyć tabele tymczasowe.
W tym przykładzie użyjemy szybkiej, prostej tabeli pochodnej. Aby to zrobić za pomocą podstawowej instrukcji select, którą utworzyliśmy w ostatniej sekcji, umieszczamy ją w nawiasach, a następnie stosujemy do niej alias. Na koniec wybieramy wszystko z tej tabeli pochodnej.
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
Stosowanie operatora przestawnego
Teraz, gdy przygotowaliśmy nasze dane bazowe i stworzyliśmy tabelę pochodną, zastosujemy do niej operator przestawny.
Aby to zrobić, wstaw „PIVOT” na końcu tabeli pochodnej, a następnie zestaw nawiasów i nadaj tej tabeli przestawnej alias.
W nawiasie musimy podać kilka ważnych informacji.
- Musimy określić pole, do którego chcemy zastosować funkcję agregującą. W naszym przypadku chcemy zastosować funkcję agregującą AVG w kolumnie „total_score”.
- Następnie musimy powiedzieć, na które kolumny z danych bazowych przestawiamy nasze dane. Robimy to, pisząc „FOR”, a następnie nazwę kolumny, która w naszym przykładzie jest miastem.
- Ostatni krok jest trochę irytujący. Musimy wymienić wartości z kolumny miasta, które mają stać się nagłówkami w naszej tabeli przestawnej. Używamy operatora IN, po którym następuje zestaw nawiasów. Wewnątrz nawiasu używamy listy oddzielonej przecinkami, w której wpisujemy nazwę każdej kolumny w nawiasie kwadratowym. W naszym przykładzie chcemy, aby nazwami nagłówków tabeli przestawnej były Londyn, Leeds i Manchester, dlatego zapisujemy je w następującym formacie:([Londyn], [Leeds], [Manchester]).
USE schooldb
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
PIVOT(
AVG(total_score)
FOR city IN ([London],[Liverpool],[Leeds],[Manchester])
) AS StudentPivotTable
Jeśli wykonasz powyższe zapytanie, wyniki będą wyglądać tak:
[identyfikator tabeli=27 /]
Dodawanie grup wierszy w tabeli przestawnej
W poprzednich sekcjach widzieliśmy, jak konwertować grupy wierszy na grupy kolumn za pomocą operatora przestawnego. Możesz jednak również dodać grupy wierszy wraz z grupami kolumn do tabeli przestawnej.
Na przykład, jeśli chcesz znaleźć średnią wartość kolumny total_score wszystkich uczniów pogrupowanych według miasta, a także według płci, możesz użyć grupy kolumn i grupy wierszy w połączeniu w tabeli przestawnej. Tutaj każda kolumna będzie reprezentować nazwę miasta, a każdy wiersz będzie reprezentować płeć ucznia.
Na szczęście nie musisz pisać żadnego dodatkowego skryptu, aby dodać grupy wierszy do tabeli przestawnej. Wewnątrz podstawowego zbioru danych po prostu dodaj nazwę kolumny, którą chcesz dodać jako grupę wierszy do tabeli przestawnej.
USE schooldb
SELECT * FROM
(SELECT
city,
gender,
total_score
FROM
student
)
AS StudentTable
PIVOT(
AVG(total_score)
FOR city IN ([London],[Liverpool],[Leeds],[Manchester])
) AS StudentPivotTable
W powyższym skrypcie po prostu dodaliśmy kolumnę „płeć” w podstawowej instrukcji SELECT.
Wynik powyższego zapytania wygląda tak:
[identyfikator tabeli=28 /]
To jest zestawienie krzyżowe. Na przykład z wyników widać, że średni całkowity wynik studentek mieszkających w Londynie wynosi 500. Podobnie średni całkowity wynik studentów mieszkających w Londynie wynosi 571.
Przeczytaj także:
Tworzenie dynamicznej tabeli przestawnej z funkcją QUOTENAME