L'operatore pivot in SQL Server converte ogni riga nel set di risultati aggregati nelle colonne corrispondenti nel set di output. L'operatore pivot è particolarmente utile nella scrittura di query di tabulazione incrociata.
Diamo un'occhiata a come funziona nella pratica.
Preparazione dei dati
Per prima cosa, creiamo alcuni dati fittizi che possiamo quindi utilizzare per implementare l'operatore pivot.
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');
Come funziona l'operatore pivot?
Il modo standard per raggruppare i dati SQL consiste nell'usare la clausola Group By. Creiamo una query che calcola la media dei valori nella colonna total_score della tabella studenti, raggruppati per città.
USE schooldb
SELECT
city,
AVG(total_score) as Avg_Score
FROM
student
GROUP BY
city
Questo dà il seguente risultato:
[id tabella=25 /]
E se volessimo un set di risultati in cui i nomi delle città siano visualizzati in colonne in cui ogni colonna contiene il valore medio del punteggio_totale degli studenti appartenenti a quella città? Qualcosa del genere:
[id tabella=26 /]
È qui che torna utile l'operatore pivot.
Selezione dei dati di base
Il primo passaggio quando si utilizza l'operatore pivot è selezionare i dati di base su cui si baserà l'operatore pivot. Vogliamo raggruppare i nostri dati per città e trovare la media del total_score degli studenti che appartengono a quella città. Pertanto, dobbiamo scrivere una semplice istruzione SELECT che seleziona la città e total_score.
SELECT
city,
total_score
FROM
student
Creazione di un set di dati temporaneo
Ora, idealmente, saremmo in grado di applicare direttamente l'operatore pivot sui dati di base che abbiamo creato nella sezione precedente, ma sfortunatamente non possiamo. Affinché l'operatore pivot funzioni, dobbiamo creare un'espressione con valori di tabella a cui possiamo applicare l'operatore pivot. Abbiamo una varietà di scelte qui; potremmo usare tabelle derivate, espressioni di tabelle comuni (CTE) o potremmo persino creare tabelle temporanee.
Per questo esempio, useremo una tabella derivata semplice e veloce. Per farlo con l'istruzione select di base che abbiamo creato nell'ultima sezione, la racchiudiamo in una serie di parentesi e quindi le applichiamo un alias. Infine, selezioniamo tutto da quella tabella derivata.
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
Applicazione dell'operatore pivot
Ora che abbiamo preparato i nostri dati di base e abbiamo creato una tabella derivata, applicheremo ad essa l'operatore pivot.
Per fare ciò, inserisci "PIVOT" alla fine della tabella derivata, seguito da una parentesi, e assegna un alias a questa tabella pivot.
Tra parentesi, dobbiamo specificare alcune informazioni importanti.
- Dobbiamo specificare il campo a cui vogliamo applicare una funzione di aggregazione. Nel nostro caso, vogliamo applicare la funzione di aggregazione AVG nella colonna "total_score".
- Dobbiamo quindi dire su quali colonne dei dati di base stiamo ruotando i nostri dati. Lo facciamo scrivendo "FOR" seguito dal nome della colonna che è una città nel nostro esempio.
- Il passaggio finale è un po' irritante. Dobbiamo elencare i valori della colonna della città che vogliamo diventino intestazioni nella nostra tabella pivot. Usiamo l'operatore IN seguito da una serie di parentesi. Tra parentesi, utilizziamo un elenco separato da virgole in cui scriviamo il nome di ciascuna colonna all'interno di una parentesi quadra. Nel nostro esempio, vogliamo Londra, Leeds e Manchester come nomi di intestazione della tabella pivot e quindi li scriviamo in questo formato:([Londra], [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
Se esegui la query precedente, i risultati saranno simili a questo:
[id tabella=27 /]
Aggiunta di gruppi di righe nella tabella pivot
Nelle sezioni precedenti, abbiamo visto come convertire i gruppi di righe in gruppi di colonne utilizzando l'operatore pivot. Tuttavia, puoi anche aggiungere gruppi di righe insieme a gruppi di colonne in una tabella pivot.
Ad esempio, se vuoi trovare il valore medio della colonna total_score di tutti gli studenti raggruppati per città e per sesso puoi utilizzare il gruppo di colonne e il gruppo di righe insieme all'interno di una tabella pivot. Qui ogni colonna rappresenterà il nome di una città e ogni riga rappresenterà il sesso di uno studente.
Fortunatamente, non è necessario scrivere alcuno script aggiuntivo per aggiungere gruppi di righe a una tabella pivot. All'interno del set di dati di base, aggiungi semplicemente il nome della colonna che desideri aggiungere come gruppo di righe alla tabella pivot.
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
Nello script precedente, abbiamo semplicemente aggiunto la colonna "genere" nell'istruzione di base SELECT.
L'output della query precedente è simile al seguente:
[id tabella=28 /]
Questa è la tabella incrociata. Ad esempio, dai risultati si può vedere che il punteggio totale medio delle studentesse che vivono a Londra è 500. Allo stesso modo, il punteggio totale medio degli studenti maschi che vivono a Londra è 571.
Leggi anche:
Creazione di tabelle pivot dinamiche con la funzione QUOTENAME