Pivotoperatorn i SQL Server konverterar varje rad i den aggregerade resultatuppsättningen till motsvarande kolumner i utdatauppsättningen. Pivotoperatorn är särskilt användbar för att skriva korstabellfrågor.
Låt oss ta en titt på hur det fungerar i praktiken.
Förbereda data
Låt oss först skapa lite dummydata som vi sedan kan använda för att implementera pivotoperatorn.
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');
Hur fungerar pivotoperatören?
Standardsättet att gruppera SQL-data är att använda Group By-satsen. Låt oss skapa en fråga som beräknar medelvärdet av värdena i kolumnen total_score i elevtabellen, grupperade efter stad.
USE schooldb
SELECT
city,
AVG(total_score) as Avg_Score
FROM
student
GROUP BY
city
Detta ger följande resultat:
[tabell id=25 /]
Vad händer om vi vill ha en resultatuppsättning där stadsnamnen visas i kolumner där varje kolumn innehåller medelvärdet av total_poängen för eleverna som tillhör den staden? Något så här:
[tabell id=26 /]
Det är här pivotoperatören kommer till användning.
Välja basdata
Det första steget när du använder pivotoperatorn är att välja den basdata som pivotoperatorn kommer att baseras på. Vi vill gruppera våra data efter stad och hitta genomsnittet av total_poängen för de elever som tillhör den staden. Därför måste vi skriva en enkel SELECT-sats som väljer stad och total_score.
SELECT
city,
total_score
FROM
student
Skapa en tillfällig datamängd
Nu skulle vi helst kunna tillämpa pivotoperatorn direkt på basdata som vi skapade i föregående avsnitt, men tyvärr kan vi inte. För att pivotoperatorn ska fungera måste vi skapa ett tabellvärderat uttryck som vi kan tillämpa pivotoperatorn på. Vi har en mängd olika val här; vi kan använda härledda tabeller, vanliga tabelluttryck (CTE) eller så kan vi till och med skapa tillfälliga tabeller.
För det här exemplet kommer vi att använda en snabb, enkel härledd tabell. För att göra det med den grundläggande select-satsen som vi skapade i det sista avsnittet, lindar vi in den i en uppsättning parenteser och applicerar sedan ett alias på den. Slutligen väljer vi allt från den härledda tabellen.
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
Använda pivotoperatören
Nu när vi har förberett vår basdata och har skapat en härledd tabell kommer vi att tillämpa pivotoperatorn på den.
För att göra detta, infoga "PIVOT" i slutet av den härledda tabellen, följt av en uppsättning parenteser, och ge denna pivottabell ett alias.
Inom parentesen måste vi ange viktig information.
- Vi måste ange fältet vi vill tillämpa en aggregatfunktion på. I vårt fall vill vi använda AVG-aggregatets funktion i kolumnen "total_score".
- Vi måste sedan säga vilka kolumner från basdata vi pivoterar våra data till. Vi gör det genom att skriva "FÖR" följt av kolumnnamnet som är en stad i vårt exempel.
- Det sista steget är lite irriterande. Vi måste lista värdena från stadskolumnen som vi vill ska bli rubriker i vår pivottabell. Vi använder IN-operatorn följt av en uppsättning parenteser. Inom parentesen använder vi en kommaseparerad lista där vi skriver namnet på varje kolumn inom en hakparentes. I vårt exempel vill vi ha London, Leeds och Manchester som rubriknamn på pivottabellen och därför skriver vi dem i detta format:([London], [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
Om du kör ovanstående fråga kommer resultaten att se ut så här:
[tabell id=27 /]
Lägga till radgrupper i pivottabellen
I de föregående avsnitten såg vi hur man konverterar radgrupper till kolumngrupper med pivotoperatorn. Du kan dock också lägga till radgrupper tillsammans med kolumngrupper i en pivottabell.
Om du till exempel vill hitta medelvärdet för kolumnen total_score för alla elever grupperade efter stad och kön kan du använda kolumngruppen och radgruppen tillsammans i en pivottabell. Här kommer varje kolumn att representera ett stadsnamn och varje rad kommer att representera ett elevkön.
Lyckligtvis behöver du inte skriva något extra skript för att lägga till radgrupper till en pivottabell. Inuti basdatauppsättningen lägger du helt enkelt till kolumnnamnet som du vill lägga till som en radgrupp i pivottabellen.
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
I skriptet ovan lade vi helt enkelt till kolumnen "kön" i basuttrycket SELECT.
Utdata från ovanstående fråga ser ut så här:
[tabell id=28 /]
Detta är en korstabell. Till exempel kan man se från resultaten att den genomsnittliga totalpoängen för kvinnliga studenter som bor i London är 500. På samma sätt är den genomsnittliga totalpoängen för manliga studenter som bor i London 571.
Läs också:
Skapa dynamisk pivottabell med funktionen QUOTENAME