Operátor pivotu na serveru SQL Server převede každý řádek v sadě agregovaných výsledků na odpovídající sloupce ve výstupní sadě. Operátor pivotu je zvláště užitečný při psaní dotazů napříč tabulkami.
Pojďme se podívat, jak to funguje v praxi.
Příprava dat
Nejprve vytvořte nějaká fiktivní data, která pak můžeme použít k implementaci pivotního operátoru.
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 funguje Pivot Operator?
Standardním způsobem seskupování dat SQL je použití klauzule Seskupit podle. Vytvořme dotaz, který vypočítá průměr hodnot ve sloupci total_score tabulky studentů, seskupených podle města.
USE schooldb
SELECT
city,
AVG(total_score) as Avg_Score
FROM
student
GROUP BY
city
Výsledkem je následující:
[id tabulky=25 /]
Co když chceme sadu výsledků, kde se názvy měst zobrazují ve sloupcích, kde každý sloupec obsahuje průměrnou hodnotu celkového_skóre studentů patřících do daného města? Něco jako toto:
[id tabulky=26 /]
Zde se hodí operátor pivotu.
Výběr základních dat
Prvním krokem při použití pivotového operátora je výběr základních dat, na kterých bude pivotní operátor založen. Chceme seskupit naše data podle města a najít průměr celkového_skóre studentů, kteří patří do daného města. Proto musíme napsat jednoduchý příkaz SELECT, který vybere město a celkové_skóre.
SELECT
city,
total_score
FROM
student
Vytvoření dočasné datové sady
Nyní bychom v ideálním případě mohli přímo aplikovat pivotový operátor na základní data, která jsme vytvořili v předchozí části, ale bohužel to nejde. Aby pivotní operátor fungoval, musíme vytvořit tabulkový výraz, na který můžeme pivotový operátor aplikovat. Máme zde různé možnosti; mohli bychom použít odvozené tabulky, běžné tabulkové výrazy (CTE) nebo dokonce vytvořit dočasné tabulky.
Pro tento příklad použijeme rychlou, jednoduchou odvozenou tabulku. Chcete-li to provést pomocí základního příkazu select, který jsme vytvořili v minulé sekci, zabalíme jej do sady závorek a poté na něj použijeme alias. Nakonec vybereme vše z této odvozené tabulky.
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
Použití otočného operátoru
Nyní, když jsme připravili naše základní data a vytvořili odvozenou tabulku, použijeme na ni pivotní operátor.
Chcete-li to provést, vložte na konec odvozené tabulky „PIVOT“ a za ním sadu závorek a přiřaďte této kontingenční tabulce alias.
V závorce musíme uvést některé důležité informace.
- Musíme zadat pole, na které chceme použít agregační funkci. V našem případě chceme použít agregační funkci AVG ve sloupci „celkové_skóre“.
- Potom musíme říci, do kterých sloupců ze základních dat převádíme naše data. Uděláme to tak, že napíšeme „PRO“ následované názvem sloupce, což je v našem příkladu město.
- Poslední krok je trochu otravný. Musíme vypsat hodnoty ze sloupce města, které se mají stát nadpisy v naší kontingenční tabulce. Používáme operátor IN následovaný sadou závorek. Uvnitř závorky používáme seznam oddělený čárkami, kde název každého sloupce zapíšeme do hranaté závorky. V našem příkladu chceme jako názvy nadpisů kontingenční tabulky London, Leeds a Manchester, a proto je zapíšeme v tomto formátu:([Londýn], [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
Pokud provedete výše uvedený dotaz, výsledky budou vypadat takto:
[id tabulky=27 /]
Přidání skupin řádků do kontingenční tabulky
V předchozích částech jsme viděli, jak převést skupiny řádků na skupiny sloupců pomocí pivotového operátoru. Můžete však také přidat skupiny řádků spolu se skupinami sloupců do kontingenční tabulky.
Chcete-li například zjistit průměrnou hodnotu sloupce celkové_skóre všech studentů seskupených podle města a také podle pohlaví, můžete použít skupinu sloupců a skupinu řádků společně v kontingenční tabulce. Zde bude každý sloupec představovat název města a každý řádek bude představovat pohlaví studenta.
Naštěstí nemusíte psát žádný další skript pro přidání skupin řádků do kontingenční tabulky. Do základní datové sady jednoduše přidejte název sloupce, který chcete přidat jako skupinu řádků do kontingenční tabulky.
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
Ve výše uvedeném skriptu jsme jednoduše přidali sloupec „gender“ do základního příkazu SELECT.
Výstup výše uvedeného dotazu vypadá takto:
[id tabulky=28 /]
Toto je křížová tabulka. Z výsledků je například vidět, že průměrné celkové skóre studentek žijících v Londýně je 500. Podobně průměrné celkové skóre studentů mužů žijících v Londýně je 571.
Přečtěte si také:
Vytvoření dynamické kontingenční tabulky pomocí funkce QUOTENAME