L'opérateur pivot dans SQL Server convertit chaque ligne du jeu de résultats agrégé en colonnes correspondantes dans le jeu de sortie. L'opérateur de pivot est particulièrement utile pour écrire des requêtes de tableau croisé.
Voyons comment cela fonctionne dans la pratique.
Préparation des données
Commençons par créer des données factices que nous pourrons ensuite utiliser pour implémenter l'opérateur 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');
Comment fonctionne l'opérateur Pivot ?
La méthode standard de regroupement des données SQL consiste à utiliser la clause Group By. Créons une requête qui calcule la moyenne des valeurs de la colonne total_score de la table des étudiants, regroupées par ville.
USE schooldb
SELECT
city,
AVG(total_score) as Avg_Score
FROM
student
GROUP BY
city
Cela donne le résultat suivant :
[identifiant de table=25 /]
Que se passe-t-il si nous voulons un ensemble de résultats où les noms des villes sont affichés dans des colonnes où chaque colonne contient la valeur moyenne du total_score des étudiants appartenant à cette ville ? Quelque chose comme ça :
[identifiant de table=26 /]
C'est là que l'opérateur pivot devient utile.
Sélectionner les données de base
La première étape lors de l'utilisation de l'opérateur pivot consiste à sélectionner les données de base sur lesquelles l'opérateur pivot sera basé. Nous voulons regrouper nos données par ville et trouver la moyenne du total_score des étudiants qui appartiennent à cette ville. Par conséquent, nous devons écrire une simple instruction SELECT qui sélectionne la ville et total_score.
SELECT
city,
total_score
FROM
student
Création d'un jeu de données temporaire
Maintenant, idéalement, nous serions en mesure d'appliquer directement l'opérateur de pivot sur les données de base que nous avons créées dans la section précédente, mais malheureusement, nous ne pouvons pas. Pour que l'opérateur pivot fonctionne, nous devons créer une expression table à laquelle nous pouvons appliquer l'opérateur pivot. Nous avons une variété de choix ici; nous pourrions utiliser des tables dérivées, des expressions de table communes (CTE) ou nous pourrions même créer des tables temporaires.
Pour cet exemple, nous utiliserons une table dérivée simple et rapide. Pour ce faire, avec l'instruction select de base que nous avons créée dans la dernière section, nous l'enveloppons dans un ensemble de parenthèses, puis nous lui appliquons un alias. Enfin, nous sélectionnons tout dans cette table dérivée.
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
Application de l'opérateur de pivot
Maintenant que nous avons préparé nos données de base et créé une table dérivée, nous allons lui appliquer l'opérateur pivot.
Pour ce faire, insérez "PIVOT" à la fin du tableau dérivé, suivi d'un ensemble de parenthèses, et attribuez un alias à ce tableau croisé dynamique.
À l'intérieur de la parenthèse, nous devons spécifier certaines informations importantes.
- Nous devons spécifier le champ auquel nous voulons appliquer une fonction d'agrégation. Dans notre cas, nous souhaitons appliquer la fonction d'agrégation AVG dans la colonne "total_score".
- Nous devons ensuite dire sur quelles colonnes des données de base nous basons nos données. Pour ce faire, nous écrivons "FOR" suivi du nom de la colonne qui est une ville dans notre exemple.
- La dernière étape est un peu irritante. Nous devons répertorier les valeurs de la colonne de la ville que nous voulons devenir des en-têtes dans notre tableau croisé dynamique. Nous utilisons l'opérateur IN suivi d'un ensemble de parenthèses. À l'intérieur de la parenthèse, nous utilisons une liste séparée par des virgules où nous écrivons le nom de chaque colonne entre crochets. Dans notre exemple, nous voulons Londres, Leeds et Manchester comme noms d'en-tête du tableau croisé dynamique et nous les écrivons donc dans ce format :([Londres], [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
Si vous exécutez la requête ci-dessus, les résultats ressembleront à ceci :
[identifiant de table=27 /]
Ajout de groupes de lignes dans le tableau croisé dynamique
Dans les sections précédentes, nous avons vu comment convertir des groupes de lignes en groupes de colonnes à l'aide de l'opérateur pivot. Cependant, vous pouvez également ajouter des groupes de lignes avec des groupes de colonnes dans un tableau croisé dynamique.
Par exemple, si vous souhaitez trouver la valeur moyenne de la colonne total_score de tous les étudiants regroupés par ville ainsi que par sexe, vous pouvez utiliser le groupe de colonnes et le groupe de lignes conjointement dans un tableau croisé dynamique. Ici, chaque colonne représentera un nom de ville et chaque ligne représentera un sexe d'étudiant.
Heureusement, vous n'avez pas besoin d'écrire de script supplémentaire pour ajouter des groupes de lignes à un tableau croisé dynamique. Dans l'ensemble de données de base, ajoutez simplement le nom de la colonne que vous souhaitez ajouter en tant que groupe de lignes au tableau croisé dynamique.
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
Dans le script ci-dessus, nous avons simplement ajouté la colonne "gender" dans l'instruction SELECT de base.
Le résultat de la requête ci-dessus ressemble à ceci :
[identifiant de table=28 /]
Il s'agit d'un tableau croisé. Par exemple, on peut voir à partir des résultats que le total_score moyen des étudiantes vivant à Londres est de 500. De même, le score total moyen des étudiants de sexe masculin vivant à Londres est de 571.
Lire aussi :
Création d'un tableau croisé dynamique dynamique avec la fonction QUOTENAME