sql >> Databasteknik >  >> RDS >> Database

Förstå Pivot Operator i SQL

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.

  1. 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".
  2. 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.
  3. 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


  1. .NET 4:Hur man konfigurerar EDMX-fil i annan assembly i Web.Config

  2. Förbereda en MySQL- eller MariaDB-server för produktion - del ett

  3. Hur ignorerar jag et-tecken i ett SQL-skript som körs från SQL Plus?

  4. Hur kan jag använda en enda mssql-anslutningspool över flera rutter i en Express 4-webbapplikation?