1- SQL - Cours
I. Introduction et vocabulaire
a) Bases de données
Les bases de données servent à... stocker des données. En particulier, elles permettent :
- de stocker beaucoup de données ;
- de pouvoir y accéder et faire des opérations dessus rapidement.
Les utilisateurs n'accèdent pas directement à la base de données : ils passent par un SGBD (Système de Gestion de Base de Données).
b) Tables
Une base de données est constituée de tables (ou entités). Voici par exemple la table Eleves de la base de données utilisée sur cette page :
Loading editor...
SELECT * FROM Eleves;
- Chaque ligne est un enregistrement (ou
-uplet) : ici, un élève. - Chaque colonne est un attribut : ici,
Prenom,Nom,Classe,AgeetVille. - Le domaine d'un attribut est l'ensemble des valeurs possibles qu'il peut prendre. Dans notre cas, ce sera entier, flottant, ou chaîne de caractères.
- La clé primaire est un identifiant unique d'un enregistrement : deux enregistrements ne peuvent pas avoir la même clé primaire. Ici, c'est le couple (
Prenom,Nom).
c) Clé étrangère
La base de données contient aussi une table Profs :
Loading editor...
SELECT * FROM Profs;
Sa clé primaire est l'attribut Classe. L'attribut Classe de la table Eleves est une clé étrangère : il fait référence à la clé primaire de la table Profs, et permet de relier chaque élève à son professeur.
II. Requêtes simples sur les bases de données
Le langage SQL est un langage simple mais puissant, qui permet d'accéder, de trier, de regrouper, de croiser... les données dans une base de données.
a) Projection
La première opération sur les bases de données est la projection. Cela permet de sélectionner seulement certains attributs (colonnes) d'une table.
Loading editor...
SELECT * FROM Eleves;
Loading editor...
SELECT Prenom, Nom FROM Eleves;
On peut ajouter plusieurs options aux projections :
- renommer des colonnes :
Loading editor...
SELECT Prenom AS P FROM Eleves;
- trier les données :
Loading editor...
SELECT * FROM Eleves ORDER BY Age DESC;
- afficher seulement certaines données :
Loading editor...
SELECT * FROM Eleves LIMIT 3 OFFSET 2;
- supprimer les doublons :
Loading editor...
SELECT DISTINCT Age FROM Eleves;
b) Sélection
Si la projection permettait de sélectionner des colonnes, la sélection, elle, permet de sélectionner des enregistrements, soit des lignes.
Loading editor...
SELECT * FROM Eleves WHERE Age = 19;
Les opérateurs de sélection sont les suivants :
=et!=pour l'égalité ;>,<,>=,<=pour les comparaisons ;AND,ORetNOTpour combiner des opérateurs.
Écrivez une requête qui renvoie le nom et le prénom des élèves de MP qui ont moins de 20 ans.
Loading editor...
SELECT Nom, Prenom FROM Eleves WHERE Classe = 'MP' AND Age < 20;Écrivez une requête qui renvoie la liste des âges des élèves de spé (MP, PC et PSI), sans doublons.
Loading editor...
SELECT DISTINCT Age FROM Eleves WHERE Classe = 'MP' OR Classe = 'PC' OR Classe = 'PSI';III. Opérations sur plusieurs tables
a) Jointures
Les jointures permettent de croiser les données de plusieurs tables, en général en fonction d'une clé étrangère. Ici, chaque élève est associé à un unique professeur (par la clé étrangère Classe), et chaque professeur à plusieurs élèves : c'est une association
Que fait la requête suivante, à votre avis ?
Loading editor...
SELECT Eleves.Prenom, Eleves.Nom, Profs.Salle FROM Eleves JOIN Profs ON Eleves.Classe = Profs.Classe;
On peut utiliser AS pour renommer les tables, et ainsi raccourcir la requête :
Loading editor...
SELECT E.Prenom, E.Nom, P.Salle FROM Eleves AS E JOIN Profs AS P ON E.Classe = P.Classe;
b) Jointures plus complexes, autojointures
On peut faire une jointure sur autre chose qu'une clé :
Loading editor...
SELECT * FROM Eleves JOIN Profs ON Eleves.Nom = Profs.Nom;
On peut joindre une table avec elle-même (c'est alors une autojointure) :
Loading editor...
SELECT * FROM Eleves AS E1 JOIN Eleves AS E2 ON
(E1.Classe = E2.Classe) AND (E1.Age = E2.Age) AND (E1.Prenom != E2.Prenom);c) Requêtes imbriquées
Le résultat d'une requête étant une table, on peut imbriquer les requêtes :
Loading editor...
SELECT DISTINCT Nom FROM (SELECT DISTINCT Nom, Age FROM Eleves WHERE Age < 19);
Écrivez une requête pour afficher le nom, le prénom, et la salle de chaque élève.
Loading editor...
SELECT E.Nom, E.Prenom, P.Salle FROM Eleves AS E JOIN Profs AS P ON E.Classe = P.Classe;Écrivez une requête pour afficher toutes les paires d'élèves qui ont le même prénom.
Loading editor...
SELECT E1.Prenom, E1.Nom, E2.Nom FROM Eleves AS E1 JOIN Eleves AS E2
ON E1.Prenom = E2.Prenom AND E1.Nom < E2.Nom; La condition E1.Nom < E2.Nom évite d'afficher un élève avec lui-même, et d'afficher chaque paire deux fois.
d) Autres opérations ensemblistes
Les opérateurs ensemblistes classiques sont disponibles sur les tables. Ces opérateurs s'utilisent seulement sur des tables avec les mêmes attributs. Ils s'utilisent en général entre deux SELECT :
Loading editor...
SELECT Nom FROM Eleves UNION SELECT Nom FROM Profs;
Les opérateurs sont UNION, INTERSECT et EXCEPT. On peut aussi faire un produit cartésien avec CROSS JOIN.
IV. Agrégats
a) Regrouper des enregistrements
Les agrégats servent à rassembler des enregistrements qui ont un attribut en commun.
Loading editor...
SELECT Age FROM Eleves GROUP BY Age;
On a également des fonctions d'agrégation qui deviennent disponibles :
Loading editor...
SELECT Age, COUNT(*) AS Nombre FROM Eleves GROUP BY Age;
Les fonctions d'agrégation disponibles sont :
COUNT(*);MIN(col)/MAX(col);SUM(col);AVG(col).
b) Ordre des opérateurs
Dans une requête, les opérateurs s'écrivent dans l'ordre suivant :
SELECT (DISTINCT)FROMJOIN .. ONWHEREGROUP BYORDER BYLIMIT .. OFFSET ..
Comment faire une restriction sur le résultat d'un agrégat ?
c) HAVING
HAVING permet de filtrer les groupes selon une condition portant sur un agrégat. Il se place juste après GROUP BY :
SELECT (DISTINCT)FROMJOIN .. ONWHEREGROUP BYHAVINGORDER BYLIMIT .. OFFSET ..
Loading editor...
SELECT Age, COUNT(*) FROM Eleves GROUP BY Age HAVING COUNT(*) > 2;
Écrivez une requête pour afficher le nombre d'élèves par salle.
Loading editor...
SELECT P.Salle, COUNT(*) AS Nombre FROM Eleves AS E
JOIN Profs AS P ON E.Classe = P.Classe
GROUP BY P.Salle;Écrivez une requête pour afficher l'élève le plus âgé de chaque prof.
Loading editor...
On calcule d'abord l'âge maximal dans chaque classe, dans une sous-requête, puis on ne garde que les élèves qui ont cet âge :
SELECT P.Nom AS Prof, E.Prenom, E.Nom, E.Age FROM Eleves AS E
JOIN Profs AS P ON E.Classe = P.Classe
JOIN (SELECT Classe, MAX(Age) AS AgeMax FROM Eleves GROUP BY Classe) AS M
ON E.Classe = M.Classe AND E.Age = M.AgeMax;