sql >> Database teknologi >  >> RDS >> Database

Forstå Pivot Operator i SQL

Pivotoperatoren i SQL Server konverterer hver række i det aggregerede resultatsæt til tilsvarende kolonner i outputsættet. Pivotoperatoren er især nyttig til at skrive krydstabuleringsforespørgsler.

Lad os tage et kig på, hvordan det fungerer i praksis.

Forberedelse af data

Lad os først oprette nogle dummy-data, som vi derefter kan bruge til at implementere pivotoperatoren.

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');

Hvordan virker pivotoperatøren?

Standardmåden til at gruppere SQL-data er ved at bruge Group By-klausulen. Lad os oprette en forespørgsel, der beregner gennemsnittet af værdierne i kolonnen total_score i elevtabellen, grupperet efter by.

USE schooldb

SELECT 
	city,
	AVG(total_score) as Avg_Score
FROM 
	student
GROUP BY
	city

Dette giver følgende resultat:

[tabel id=25 /]

Hvad hvis vi ønsker et resultatsæt, hvor bynavnene vises i kolonner, hvor hver kolonne indeholder gennemsnitsværdien af ​​total_score for de elever, der tilhører den by? Noget som dette:

[tabel id=26 /]

Det er her, pivotoperatøren er praktisk.

Valg af basisdata

Det første trin, når du bruger pivotoperatoren, er at vælge de basisdata, som pivotoperatoren vil være baseret på. Vi ønsker at gruppere vores data efter by og finde gennemsnittet af total_score for de elever, der tilhører den by. Derfor skal vi skrive en simpel SELECT-sætning, der vælger byen og total_score.

SELECT 
	city,
	total_score
FROM 
	student

Oprettelse af et midlertidigt datasæt

Nu, ideelt set, ville vi være i stand til direkte at anvende pivotoperatoren på de basisdata, som vi oprettede i det foregående afsnit, men det kan vi desværre ikke. For at pivot-operatoren skal fungere, skal vi lave et tabelværdi-udtryk, som vi kan anvende pivot-operatoren på. Vi har en række valgmuligheder her; vi kunne bruge afledte tabeller, almindelige tabeludtryk (CTE'er), eller vi kunne endda oprette midlertidige tabeller.

Til dette eksempel vil vi bruge en hurtig, enkel afledt tabel. For at gøre det med den grundlæggende select-sætning, som vi oprettede i sidste afsnit, pakker vi den ind i et sæt parenteser og anvender derefter et alias til den. Til sidst vælger vi alt fra den afledte tabel.

SELECT * FROM

(SELECT 
	city,
	total_score
FROM 
	student
)
AS StudentTable

Anvendelse af pivotoperatøren

Nu hvor vi har forberedt vores basisdata og har oprettet en afledt tabel, vil vi anvende pivotoperatoren på den.

For at gøre dette skal du indsætte "PIVOT" i slutningen af ​​den afledte tabel, efterfulgt af et sæt parenteser, og give denne pivottabel et alias.

Inde i parentesen skal vi angive nogle vigtige oplysninger.

  1. Vi skal angive det felt, vi vil anvende en aggregeret funktion på. I vores tilfælde ønsker vi at anvende AVG-aggregatfunktionen i kolonnen "total_score".
  2. Vi skal så sige, hvilke kolonner fra basisdataene vi pivoterer vores data til. Det gør vi ved at skrive "FOR" efterfulgt af kolonnenavnet, som er en by i vores eksempel.
  3. Det sidste trin er lidt irriterende. Vi skal angive de værdier fra bykolonnen, som vi ønsker skal blive overskrifter i vores pivottabel. Vi bruger IN-operatoren efterfulgt af et sæt parenteser. Inde i parentesen bruger vi en kommasepareret liste, hvor vi skriver navnet på hver kolonne inden for en firkantet parentes. I vores eksempel ønsker vi London, Leeds og Manchester som overskriftsnavne på pivottabellen, og derfor skriver vi dem i dette 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

Hvis du udfører ovenstående forespørgsel, vil resultaterne se sådan ud:

[tabel id=27 /]

Tilføjelse af rækkegrupper i pivottabel

I de foregående afsnit så vi, hvordan man konverterer rækkegrupper til kolonnegrupper ved hjælp af pivotoperator. Du kan dog også tilføje rækkegrupper sammen med kolonnegrupper til en pivottabel.

For eksempel, hvis du vil finde gennemsnitsværdien af ​​kolonnen total_score for alle elever grupperet efter by såvel som efter køn, kan du bruge kolonnegruppen og rækkegruppen sammen inde i en pivottabel. Her vil hver kolonne repræsentere et bynavn, og hver række vil repræsentere et elevkøn.

Heldigvis behøver du ikke skrive noget ekstra script for at tilføje rækkegrupper til en pivottabel. Inde i basisdatasættet skal du blot tilføje kolonnenavnet, som du vil tilføje som en rækkegruppe til 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 ovenstående script tilføjede vi simpelthen "køn"-kolonnen i basis SELECT-sætningen.

Outputtet af ovenstående forespørgsel ser sådan ud:

[tabel id=28 /]

Dette er krydstabulering. For eksempel kan det ses af resultaterne, at den gennemsnitlige total_score af kvindelige studerende, der bor i London, er 500. På samme måde er den gennemsnitlige samlede score for mandlige studerende, der bor i London, 571.

Læs også:

Oprettelse af dynamisk pivottabel med funktionen QUOTENAME


  1. Vælg ulåst række i Postgresql

  2. Opret en Excel-fil (.xlsx) ved hjælp af PL/SQL

  3. Sådan formindskes/renses ibdata1-fil i MySQL

  4. Hvordan returnerer man resultatet af en SELECT i en funktion i PostgreSQL?