Aller au contenu

Cours

1. Le langage SQL⚓︎

1.1 Présentation⚓︎

Le SQL (Structured Query Language) est un « langage de programmation » particulier qui permet de manipuler des bases de données relationnelles.
SQL se retrouve aujourd'hui dans la très grande majorité des SGBD, et fonctionne sur des plates-formes allant des gros systèmes aux micro-ordinateurs.
Exemple de SGBD utilisant SQL pour la gestion des données : MS-ACCESS, ORACLE, SQL SERVER, MySQL, PostgreSQL, etc.
SQL n'est pas un langage de programmation au sens classique du terme, c'est un langage qui permet de faire des manipulations sur des bases de données à l'aide d'un système de requêtes.

1.2 Classification des commandes⚓︎

Le langage SQL contient trois grandes familles de commandes :

  • Le langage de description de données (LDD) qui permet la création et la modification de la structure de bases de données (tables et attributs, vues, états, index, contraintes d'intégrité ...)

  • Le langage de contrôle des données (LCD) qui assure la sécurité des données, et leur confidentialité (qui a le droit de faire quoi, et sur quoi ?), réservé à l'administrateur de la base.

  • Le langage de manipulation de données (LMD) qui permet la gestion des données se trouvant dans les tables (consultation, mise à jour, ...)

Dans ce chapitre, nous étudierons uniquement le langage de manipulation des données.  

2. Présentation du thème⚓︎

Pour illustrer les commandes de base du langage de manipulation de données SQL, nous utiliserons le système d’information décrit ci-après.

2.1 Modèle logique des Données (schéma relationnel)⚓︎

Représentation graphique⚓︎

base VOL

Représentation en intention⚓︎

PILOTE(NumPilote, NomPilote, Adresse, Salaire, Bonus)
AVION(NumAvion, NomAvion, Capacite)
VOL(NumVol, VilleDepart, VilleArrivee, HeureDepart, HeureArrivee, #NumAvion, #NumPilote)

Représentation détaillée :⚓︎

📋 Texte
PILOTE(NumPilote, NomPilote, Adresse, Salaire, Bonus) 
    NumPilote : Clé primaire 
AVION(NumAvion, NomAvion, Capacite) 
    NumAvion : Clé primaire
 VOL(NumVol, VilleDepart, VilleArrivee, HeureDepart, HeureArrivee, NumAvion, NumPilote)
    NumVol : Clé primaire 
    NumAvion : Clé étrangère en référence à NumAvion de AVION 
    NumPilote : Clé étrangère en référence à NumPilote de PILOTE

2.2 Modèle physique des Données⚓︎

MPD Base VOL

2.3 Contenu de la base de données⚓︎

Contenu Table PILOTE

Contenu Table AVION

Contenu Table VOL

Base VOL

Télécharger fichier Création de la base VOL ⬇️

Créer la base VOL comme indiqué lors du TP1.
indication :
- Créer une nouvelle Base.
- Dans l'onglet SQL, copier/coller le script téléchargé juste au dessus.
- Vérifier dans le volet de gauche que vous avez toutes vos tables ainsi que les données.

3. La Consultation des données⚓︎

La consultation (ou l’interrogation) des données constitue l’opération la plus fréquemment utilisée en langage SQL. Elle est réalisée en utilisant la commande SELECT.

Sa syntaxe générale est la suivante :

🐬 SQL
SELECT [ALL] | [DISTINCT] <liste des noms de colonnes> | *
 FROM <Liste des tables>
 [WHERE <condition logique>] 
Note : Les instructions entre crochets [ ] sont facultatives.

3.1 La projection⚓︎

Cette opération permet de sélectionner une partie des attributs d'une ou plusieurs tables.

R1

Quels renseignements possédons-nous sur tous les avions ?

NumAvion NomAvion Capacite
1 A340-300 295
2 ATR72 70
3 B747-400 420
4 A319 120
5 ATR42/72 50
6 B747-400 420
🐬 SQL
SELECT * 
FROM AVION ;

Tous les tuples de la relation AVION sont ainsi sélectionnés.

La projection peut être limitée à un choix d’attributs en indiquant, à la place de l’astérisque (*), une liste de noms d’attributs.

R2

Quels sont les noms et les capacités des avions de la compagnie?

NomAvion Capacite
A340-300 295
ATR72 70
B747-400 420
A319 120
ATR42/72 50
B747-400 420
🐬 SQL
SELECT nomAvion, capacite
FROM AVION ;

La clause DISTINCT ajoutée à la clause SELECT permet d’éliminer les doublons (dans notre cas, les infos sur le B747-400).
Ainsi, si dans le résultat plusieurs tuples sont identiques, un seul sera conservé.

R3

Quels sont les différents avions de la compagnie et leur capacité ?

NomAvion Capacite
A340-300 295
ATR72 70
B747-400 420
A319 120
ATR42/72 50
🐬 SQL
SELECT DISTINCT nomAvion, capacité
FROM AVION ;

Note : L'option ALL est, par opposition à l'option DISTINCT, l'option par défaut. Elle permet de sélectionner l'ensemble des lignes.

3.2 La sélection (ou restriction)⚓︎

La sélection est l'opération qui permet de sélectionner des occurrences d'une ou plusieurs tables répondant à certains critères.
En SQL, les restrictions s'expriment à l'aide de la clause WHERE suivie d'une condition logique exprimée à l'aide d'opérateurs logiques. La condition (expression logique booléenne Vrai/Faux) sera évaluée pour chaque occurrence. Les tuples pour lesquels la condition est «Vraie » sont ainsi sélectionnés.

3.2.1 Condition logique simple⚓︎

C’est le résultat de la comparaison de deux expressions au moyen d’un opérateur de comparaison :

Symbole opération
= egalité
!= ou < > DIfférence
> et >= supériorité
< et <= inferiorité
BETWEEN AND Intervalle
LIKE comparaison sur chaîne de caractère
IN () appartenance à une liste de valeurs
LIKE %

Le prédicat LIKE permet de faire des comparaisons sur des chaînes grâce à des caractères, appelés caractères jokers. Ces caractères peuvent être différents suivant le SGBDR utilisé. Il faut se Référer à la documentation du SGBDR. Pour MySQL, il s'agit du %

🔃 LIKE '%a' : le caractère “%” est un caractère joker qui remplace tous les autres caractères. Ainsi, ce modèle permet de rechercher toutes les chaines de caractère qui se termine par un “a”.
🔃 LIKE 'a%' : ce modèle permet de rechercher toutes les lignes de “colonne” qui commence par un “a”.
🔃 LIKE '%a%' : ce modèle est utilisé pour rechercher tous les enregistrement qui utilisent le caractère “a”.
🔃 LIKE 'pa%on' : ce modèle permet de rechercher les chaines qui commence par “pa” et qui se terminent par “on”, comme “pantalon” ou “pardon”.
🔃 LIKE 'a_c' : peu utilisé, le caractère “_” (underscore) peut être remplacé par n’importe quel caractère, mais un seul caractère uniquement (alors que le symbole pourcentage “%” peut être remplacé par un nombre incalculable de caractères . Ainsi, ce modèle permet de retourner les lignes “aac”, “abc” ou même “azc”. Source sql.sh

R4

Quels sont les avions de capacité supérieure ou égale à 100

NomAvion Capacite
A319 120
A340-300 295
B747-400 420
🐬 SQL
SELECT nomAvion, capacite
FROM AVION
WHERE capacite >= 100 ;

R5

Quels sont les pilotes (Nom, Bonus et Salaire) dont le bonus est supérieur au salaire ?

nompilote bonus salaire
TOTO 110 100
🐬 SQL
SELECT nomPilote, bonus, Salaire
FROM PILOTE
WHERE bonus > salaire ;

R6

Quels sont les pilotes dont le bonus est compris entre 800 et 1000 € ?

nompilote bonus
PAYET 800
HOAREAU 950
DUPUIS 900
DUPOND 1000
🐬 SQL
SELECT nomPilote, bonus
FROM PILOTE
WHERE bonus BETWEEN 800 AND 1000 ;

R7

Quels sont les pilotes dont le nom commence par "DUP" ?

nompilote
DUPUIS
DUPOND
🐬 SQL
SELECT nomPilote
FROM PILOTE
WHERE nomPilote LIKE "DUP%" ;

R8

Quels sont les numéros des vols dont la ville d’arrivée est "GILLOT" ou "MAURICE" ?

NumVol
AF 380
MK 203
MK 230
MK 45
🐬 SQL
SELECT numVol
FROM VOL
WHERE villeArrivee IN ('GILLOT','MAURICE') ;

3.2.2 Conditions logiques composées⚓︎

Les opérateurs logiques AND et OR sont utilisés pour combiner plusieurs conditions.
Ainsi, les requêtes R6 et R8 peuvent être écrites d'une autre façon :

R6 bis

Quels sont les pilotes dont le bonus est compris entre 800 et 1000 € ?

nompilote bonus
PAYET 800
HOAREAU 950
DUPUIS 900
DUPOND 1000

🐬 SQL
SELECT nomPilote, bonus
FROM PILOTE
WHERE bonus >= 800 AND bonus <= 1000 ;
note : le champ de restriction doit absolument être répété.

R8 Bis

Quels sont les numéros des vols dont la ville d’arrivée est "GILLOT" ou "MAURICE" ?

NumVol
AF 380
MK 203
MK 230
MK 45

🐬 SQL
SELECT numVol
FROM VOL
WHERE villeArrivee = 'GILLOT' OR villeArrivee ='MAURICE';
note : le champ de restriction doit absolument être répété. note 2 : On ne peut pas mettre l'opérateur AND ici car une ville ne peut pas en même temps être GILLOT et Maurice.

R9

Quels sont les pilotes dont le bonus est inférieur à 800€ (peu importe la ville où ils résident) et ceux dont le salaire est inférieur à 3500€ mais habitant PARIS ?

NomPilote bonus salaire Adresse
DUPUIS 900 3200 75130 Paris
PETIT 500 2000 34000 Montpellier
🐬 SQL
SELECT nomPilote, bonus, salaire, adresse
FROM PILOTE
WHERE (bonus <800) OR
      (salaire < 3500 AND adresse LIKE "%Paris");

Remarques : - L’opérateur AND est prioritaire par rapport à l’opérateur OR.

🐬 SQL
SELECT nomPilote, bonus, salaire, adresse
FROM PILOTE
WHERE bonus <800 OR
      salaire < 3500 AND adresse LIKE "%Paris";

R9 bis

Quels sont les pilotes qui habitent à Ste-Marie ou à St-Denis et dont le bonus est supérieur à 1000€ ?

NomPilote bonus
TOTO 1100

🐬 SQL
SELECT nomPilote, bonus
FROM PILOTE
WHERE (adresse LIKE "%STE MARIE" OR adresse LIKE "%ST DENIS") AND bonus > 1000 ;
note : le parenthésage est ici obligatoire.

3.2.3 Restriction sur une valeur manquante⚓︎

Lorsqu'un champ n'est pas renseigné, le SGBD lui attribue une valeur spéciale que l'on note NULL. La recherche de cette valeur ne peut pas se faire à l'aide des opérateurs classiques, il faut utiliser les prédicats IS NULL ou bien IS NOT NULL.

null différent de zéro

R10

Quels sont les pilotes n’ayant pas de bonus ?

NumPilote NomPilote bonus
7 VITRI
🐬 SQL
SELECT NumPilote, NomPilote, bonus
FROM PILOTE
WHERE bonus IS NULL ;

3.3 Interrogation de plusieurs tables : la jointure⚓︎

jointure

La jointure est l’opération permettant d’obtenir des informations provenant de plusieurs tables.
Une jointure est formulée en spécifiant :
- les relations concernées dans la clause FROM
- Les attributs concernés par la relation d'intégrité référentielle.

Note : Les jointures portent TOUJOURS sur les clés primaires et les clés étrangères des relations.

Exemple : « Pour chaque numéro de vol, on désire connaître le nom des avions »

Cette requête concerne des attributs provenant de plusieurs relations :
- NumVol dans la relation VOL
- NomAvion dans la relation AVION

3.3.1 Syntaxe SQL92 (SQL-2)⚓︎

La clause FROM, combinée avec une nouvelle clause INNER JOIN, devra indiquer la liste des relations concernées : VOL et AVION ainsi que les champs sur lesquels portera la jointure.
l'égalité de jointure devra se faire sur les champs en égalité ... Ici, l'intégrité référentielle entre les tables VOL et AVION se fait sur les champs numAvion de AVION (clé primaire) et numAvion de VOL (clé étrangère).
La clause WHERE contiendra les éventuelles restrictions.
💪 C’est le point fort du SQL-2 : séparer ce qui relève de la jointure du reste de la requête.

R11

Pour chaque numéro de vol, on désire connaître le nom des avions

NumVol NomAvion
MK 45 A340-300
MK 230 ATR72
AF 380 B747-400
AF 7684 A319
MK 203 ATR42/72
MK 40 B747-400
🐬 SQL
SELECT NumVol, NomAvion
FROM VOL INNER JOIN AVION
ON VOL.numAvion = AVION.numAvion ;

note : dans notre requête, numAvion désigne deux champs différents dans la base VOL. Il est nécessaire de préciser celui dont on parle, en préfixant le champ avec le nom de sa table.

Si ce n'est pas fait, le moteur SQL provoquera une erreur #1052 - Champ: 'numAvion' dans on clause est ambigu

R12

Nom du pilote qui assure le vol "AF7684"

NomPilote
PETIT
🐬 SQL
SELECT nomPilote
FROM PILOTE INNER JOIN VOL
ON PILOTE.numPilote = VOL.numPilote
WHERE numVol = 'AF7684' ;

R13

Nom des pilotes qui ont déjà piloté un "BOEING 747-400" ?

NomPilote
TOTO
PAYET
🐬 SQL
SELECT nomPilote
FROM PILOTE INNER JOIN VOL
ON PILOTE.numPilote = VOL.numPilote
INNER JOIN AVION
ON AVION.numAvion = VOL.numAvion
WHERE nomAvion LIKE "%747-400%" ;

3.3.2 Syntaxe SQL89 (SQL-1)⚓︎

Une plus ancienne façon d'écrire les jointures existe dans la norme SQL-1. Mais elle est bien moins performante que les jointures interne INNER JOIN. Elle est présenté ici car elle peut être croiser dans des "vieux" codes. On pourra la nommer "equi-jointure".

La clause FROM devra indiquer la liste des relations concernées : VOL et AVION.

La clause WHERE devra contenir : - une condition sur l'égalité de jointure. Si les attributs concernés portent le même nom, on les préfixera du nom de la relation correspondante. - Des conditions de restrictions en fonction du besoin

R11 SQL-1

Pour chaque numéro de vol, on désire connaître le nom des avions

NumVol NomAvion
MK 45 A340-300
MK 230 ATR72
AF 380 B747-400
AF 7684 A319
MK 203 ATR42/72
MK 40 B747-400
🐬 SQL
SELECT NumVol, NomAvion
FROM VOL, AVION
WHERE VOL.numAvion = AVION.numAvion ;

R12 SQL-1

Nom du pilote qui assure le vol "AF7684"

NomPilote
PETIT
🐬 SQL
SELECT nomPilote
FROM PILOTE,VOL
WHERE PILOTE.numPilote = VOL.numPilote 
    AND numVol = 'AF7684';

R13 SQL-1

Nom des pilotes qui ont déjà piloté un "BOEING 747-400" ?

NomPilote
TOTO
PAYET
🐬 SQL
SELECT nomPilote
FROM PILOTE , VOL
WHERE PILOTE.numPilote = VOL.numPilote
    AND nomAvion LIKE "%747-400%" ;

3.4 Tri des résultats⚓︎

order by

Les tuples constituant le résultat d’une requête sont obtenus dans un ordre indéterminé dépendant des mécanismes internes du SGBDR utilisé. On peut demander en fin d’instruction SELECT que le résultat soit ordonné de manière ascendante ou descendante suivant un ou plusieurs attributs.
Les critères de tri sont indiqués dans la clause ORDER BY dont la syntaxe est la suivante :

🐬 SQL
ORDER BY <Attribut 1> [ASC/DESC], <Attribut 2> [ASC/DESC],  

Le tri se fait tout d’abord selon le premier attribut, puis les tuples ayant une même valeur pour ce premier attribut sont classées selon le deuxième attribut, etc… Par attribut, le tri peut être ascendant (ASC par défaut) ou descendant (DESC).

R14

Liste détaillée des avions triée par ordre alphabétique croissant (sur NomAvion)

NumAvion NomAvion Capacite
1 A340-300 295
2 ATR72 70
3 B747-400 420
4 A319 120
5 ATR42/72 50
6 B747-400 420
🐬 SQL
SELECT numAvion, NomAvion, capacite
FROM AVION
ORDER BY nomAvion ASC; /*ASC est facultatif, car c est la valeur par defaut*/

R15

Liste des pilotes ayant un bonus. Les bonus seront classés dans l’ordre décroissant

NomPilote Bonus
TOTO 1100
DUPOND 1000
HOAREAU 950
DUPUIS 900
PAYET 800
PETIT 500
🐬 SQL
SELECT NomPilote, bonus
FROM PILOTE
WHERE bonus IS NOT NULL
ORDER BY bonus DESC ;

note : On peut très bien trié un attribut non présent dans la projection (ie dans la clause SELECT)

3.5 Calculs arithmétiques⚓︎

3.5.1 Calculs sur attributs⚓︎

Les attributs numériques d’une table peuvent être utilisés pour réaliser des calculs. On réalise alors directement les principales opérations mathématiques dans les clauses SELECT ou WHERE.

R16

Quels sont les pilotes qui gagnent plus de 4200 € (bonus compris) ?

NomPilote
HOAREAU
DUPOND
🐬 SQL
SELECT nomPilote
FROM PILOTE
WHERE (salaire + bonus) > 4200 OR salaire > 4200 ;

3.5.2 Les fonctions intégrées⚓︎

Les fonctions suivantes du langage SQL effectuent un calcul sur des ensembles de valeurs.

🐬 SQL
AVG(<Attribut>) : Moyenne arithmétique 
SUM(<Attribut>) : Somme arithmétique 
MAX(<Attribut>) : Valeur maximum 
MIN(<Attribut>) : Valeur minimum 
COUNT(*), COUNT(<Attribut>), COUNT(DISTINCT <Attribut>) : Nombre de tuples
Ils s'utilisent EXCLUSIVEMENT dans la clause SELECT (ou dans la clause HAVING que l'on verra un peu plus tard)

R17

Quel est le salaire moyen des pilotes?

Expr1000
2514.2857
🐬 SQL
SELECT AVG(salaire)
FROM PILOTE ;

Note : L'utilisation de AS permet de donner un nom d’alias au calcul résultant.

R18

Quel est le plus gros salaire ?

PlusGrosSalaire
3500
🐬 SQL
SELECT MAX(salaire) AS plusGrosSalaire
FROM PILOTE ;

R19

Combien d’avions disposent de plus de 100 places ?

NbPlus100
4
🐬 SQL
SELECT COUNT(*)
FROM AVION
WHERE capacite > 100 ;

R20

Combien d’avions existe-t-il ?

NAvion
6
🐬 SQL
SELECT COUNT(*)
FROM AVION ;

Mais en réalité, il n'y en a que 5 modèles. On peut affiner notre requête en utilisant la clause DISTINCT déjà vu.

R20 bis

Combien d’avions différents existe-t-il ?

NAvion
5
🐬 SQL
SELECT  COUNT(DISTINCT nomAvion)
FROM AVION ;

R21

Quel est le pourcentage de pilotes avec bonus ?

PiloteAvecBonus
85,7142857142857
🐬 SQL
SELECT COUNT(bonus)/COUNT(*)x100
FROM PILOTE ;

3.6 Regroupement des résultats⚓︎

Il peut être intéressant de regrouper des résultats afin de faire des opérations par groupe (opérations statistiques par exemple). Cette opération se réalise à l'aide de la clause GROUP BY, suivie du nom de chaque colonne sur laquelle on veut effectuer des regroupements.

R22

Combien y a-t-il de vol(s) au départ de chaque ville ? »

VilleDepart NbVols
GILLOT 2
MAURICE 1
PARIS CDG 2
PARIS ORLY 1
🐬 SQL
SELECT VilleDepart, COUNT(*) AS nbVols
FROM VOL 
GROUP BY VilleDepart ;

R23

Combien y a-t-il de places tous vols confondus au départ de chaque ville ?

VilleDepart NbPlaces
GILLOT 120
MAURICE 420
PARIS CDG 415
PARIS ORLY 420
🐬 SQL
SELECT VilleDepart, SUM(capacite) AS NbPlaces
FROM VOL INNER JOIN AVION
ON VOL.numAvion = AVION.numAvion
GROUP BY VilleDepart ;

Explication

La clause HAVING va de pair avec la clause GROUP BY, elle permet d'appliquer une restriction sur les groupes créés grâce à la clause GROUP BY. On introduit le filtre HAVING qui porte, non pas sur les données, mais sur les calculs résultants des regroupements.

⚠️ Attention à ne pas confondre HAVING et WHERE : HAVING permet la sélection de groupes à la suite d’une requête avec regroupement alors que WHERE permet de sélectionner des lignes pour construire la requête.

R24

Quelles sont les villes pour lesquelles il y a au moins 2 vols à l’arrivée »

VilleArrivee NbArrivee
GILLOT 2
MAURICE 2
🐬 SQL
SELECT VilleDepart, COUNT(*) AS nbVols
FROM VOL 
GROUP BY VilleDepart 
HAVING COUNT(*) >= 2 ;

4. Mise à jour des données⚓︎

4.1 Ajout de données⚓︎

L'insertion de nouvelles données dans une table se fait grâce à la commande 'INSERT'.
Sa syntaxe générale est la suivante :

🐬 SQL
INSERT INTO Nom_de_la_table ([Attr1],[Attr2], )
VALUES (Valeur1,Valeur2,Valeur3,...) 
Notes :
- Les données sont affectées aux colonnes dans l'ordre dans lequel elles ont été créées.
- Lorsque les valeurs sont des chaînes de caractères, il faut les délimiter par des guillemets.

Ra

Ajouter l’avion suivant dans la base : N°7 ; Modèle A319 ; capacité 100

🐬 SQL
INSERT INTO AVION(numAvion, NomAvion, capacite)
VALUES (7 , "A319", 100) ;

4.2 Modification de données⚓︎

La modification de données consiste à modifier des occurrences dans une table à l’aide de la commande UPDATE. La modification à effectuer est précisée après la clause SET.
Sa syntaxe générale est la suivante :

🐬 SQL
UPDATE Nom_de_la_table 
SET Attribut1 = Valeur_Ou_Expression1 [, Attribut2 = Val_Ou_Expr2]... [WHERE Conditions] 

Note :
- Valeur_Ou_Expression peut être une expression algébrique, une constante ou un résultat provenant d'une clause SELECT.
- La clause facultative WHERE permet de préciser les tuples sur lesquels la mise à jour aura lieu. L'oublier, sera alors dommageable. Toutes les valeurs de cet attribut serait mis à jour ! Et je vous rappelle qu'il n'existe pas de CTRL+Z en base de données !

Rb

Appliquer une augmentation de 5% sur le salaire de tous les pilotes

🐬 SQL
UPDATE PILOTE
SET salaire = salaire * 1.05 ;

Rc

Pour tous les pilotes (y compris sans bonus), majorer de 25€ les bonus inférieurs à 1000€

🐬 SQL
UPDATE PILOTE
SET bonus = bonus + 25
WHERE bonus < 1000 ;
/*ET */
UPDATE PILOTE
SET bonus = 25
WHERE bonus IS NULL ;
Cette mise à jour nécessite deux requêtes pour pouvoir prendre en compte les bonus ayant pour valeur « Null »
Remarque : Dans le cas présent, il était plus judicieux d’affecter au bonus une valeur nulle (zéro) par défaut.

4.3 Suppression de données⚓︎

La suppression de données dans une table se fait grâce à la commande DELETE.
- La clause FROM précise la table sur laquelle la suppression s'effectue.
- La clause WHERE précise l'ensemble des lignes qui seront supprimées.
Sa syntaxe générale est la suivante :

🐬 SQL
DELETE FROM Nom_de_la_table 
[WHERE Condition] 

Note :
- La commande DELETE est à utiliser avec précaution car l'opération de suppression est irréversible.
- Il préférable et surtout plus prudent de s'assurer dans un premier temps que les lignes sélectionnées sont bien les lignes que l'on désire supprimer !
- La clause WHERE est facultative mais sera la plupart du temps renseignée sans quoi, c’est le contenu complet de la table qui sera effacé. Rd : « »

Rd

Supprimer l’avion ajouté par la requête Ra

🐬 SQL
DELETE FROM AVION
WHERE numAvion = 7 ;

Télécharger fichier Correction des requêtes ⬇️