Chapitre 3:
SQL :
Le Langage
d’interrogation des bases
de données (LID)
2
Interroger les BDDs relationnelles?
Une seule instruction: SELECT
Exemple (fil rouge sur l’ensemble du
chapitre)
Soit la BDD composée des relations
suivantes :
▫ Produit (Nump, nomp, prix)
▫ Depot (Numdep, libellé, adr-dep)
▫ Stock (Nump, Numdep, qte)
3
Exprimer la projection ?
Syntaxe :
SELECT [ ALL/DISTINCT] < expression de
valeurs>
FROM nom de relation
<Expression de valeurs>: expression
arithmétique composée :
d’opérateurs binaires ( +, -, *, /)
de constantes
de colonnes.
4
Projection: exemples
Q1) donner la liste des numéros de
produits :
SELECT Nump
FROM Produit
Q2) donner les noms de produits
(possibilité d’homonymie)
SELECT DISTINCT Nomp
FROM Produit
5
Exprimer la sélection ?
Syntaxe :
SELECT *
FROM nom-table
WHERE qualification (condition de
recherche)
• Une condition de recherche élémentaire
est appelée prédicat en SQL.
• Un prédicat compare deux expressions de
valeurs ; la première est appelée terme
(contenant des colonnes) et la seconde
6
Prédicats en SQL
Prédicat de comparaison : Les opérateurs { =, !=,
<, >, >=, <= }
Prédicat d’intervalle : BETWEEN
Prédicat de comparaison de texte : LIKE
Prédicat de test de nullité : IS NULL
Prédicat d’appartenance : IN
7
Exprimer la sélection ?
Exemples :
• La liste des numéros de produits dont le prix est > 1500DA?
SELECT Nump
FROM Produit
WHERE prix> 1500;
• La liste des numéros de produits dont le prix est compris entre
100 et 300 DA et le nom commence par la lettre ‘A’ ?
SELECT Nump
FROM Produit
WHERE prix BETWEEN 100 AND 300
AND nomp LIKE ‘A%’;
8
Exprimer la sélection ?
• Parmi les noms de produits (chaise, table,
tableau, stylo, papier), quels sont ceux dont le
prix est inconnu ?
SELECT Nump
FROM Produit
WHERE nomp IN (‘chaise’, ‘table’, ‘tableau’, ‘stylo’,
‘papier’)
AND prix IS NULL;
9
Exprimer le produit cartésien ?
• le produit cartésien s’exprime comme une
jointure sans qualification :
Syntaxe :
SELECT *
FROM liste de noms de relations
Exemples :
• La requête en algèbre relationnelle : P := produit
stock s’exprime en SQL comme suit :
SELECT *
FROM Produit, Stock;
10
Exprimer la jointure ?
La jointure avec qualification peut être exprimée en SQL de
plusieurs manières
• en utilisant la restriction (la sélection) du produit
cartésien :
SELECT *
FROM liste de noms de relations
WHERE condition de jointure
• En utilisant l’imbrication des requêtes.
Remarque :
les opérateurs de jointure, de sélection et de projection
peuvent être combinés et effectués à l’intérieur d’une
même clause SELECT.
11
Exprimer la jointure ?
Quel est le numéro et le nom des produits en
rupture de stock dans l’un des dépôts? (quantité
= 0) ?
1ère formulation 2ème formulation
SELECT Nump, nomp SELECT Nump, nomp
FROM Produit, Stock FROM Produit
WHERE WHERE Nump IN
Produit.Nump = (SELECT Nump
Stock.Nump FROM Stock
AND Stock.qte = 0 WHERE Stock.qte = 0)
12
Exprimer la jointure ?
• Donner l’adresse des dépôts qui stockent le produit
de nom ‘table’.
2ème formulation :
1 ère
formulation :
SELECT Numdep, adr-dep SELECT Numdep, adr-dep
FROM Produit, Depot, Stock FROM Depot
WHERE WHERE Numdep IN
Produit.Nump = Stock.Nump (SELECT Numdep
AND FROM Stock
Depot.Numdep
WHERE Nump
=Stock.Numdep
IN (SELECT Nump
AND
Produit.nomp LIKE ‘table’;
13
Alias ou synonyme de relations ?
3 formes pour désigner les attributs d’une relation
• Nom-attribut, si non ambiguïté
• Nom-relation.nom-attribut si ambiguité
• Alias-relation.nom-attribut si ambiguïté.
Un alias : un nom de variable attribué à une relation dans la clause
FROM afin d ‘éviter de répéter le nom complet des relations dans
les critères (conditions)
Remarque :
Un attribut sous la 1ère forme (nomattribut) référence la relation la
plus interne qui a un attribut de ce nom là.
14
Exemple2
• Schéma de la BDD exemple :
• Employé(cod-emp, nom-emp, dat-recrut, cod-poste,
salaire, prime, supérieur, cod-dep)
• Département(cod-dep, nom-dep, cod-respon)
• Poste( cod-poste, intitulé, salair-min, salair-max)
• Historique-poste( cod-emp, cod-poste, cod-dep, dat-
debut, dat-fin)
15
Clause ORDER BY
ORDER BY précise l'ordre dans lequel la liste des lignes
sélectionnées dans le résultat sera affichée.
Syntaxe : ORDER BY exp1 [DESC], exp2 [DESC], ...
DESC : tri par ordre décroissant. Par défaut, l'ordre est
croissant.
Le tri se fait d'abord selon la première expression, puis les
lignes ayant la même valeur pour la première expression
sont triées selon la deuxième, etc.
Les valeurs nulles sont toujours en tête quel que soit l'ordre
du tri
16
ORDER BY : Exemples
Liste des noms d’employés et de leur poste, triée
par département et dans chaque département par
ordre de salaire décroissant :
SELECT nomemp, codposte
FROM employe
ORDER BY coddep , salaire DESC;
17
Opérateurs ensemblistes
Opérateur UNION
• fusionner deux sélections de tables pour obtenir un
ensemble de lignes égal à la réunion des lignes des deux
sélections.
• Les lignes communes n'apparaîtront qu'une fois.
Syntaxe: (les deux tables ont le même schéma)
SELECT * FROM table1 WHERE …
UNION
SELECT * FROM table2 WHERE …
18
Opérateurs ensemblistes
Opérateur INTERSECT
• Permet d'obtenir l'ensemble des lignes
communes à deux interrogations.
Syntaxe: (les deux tables ont le même schéma)
SELECT * FROM table1 WHERE …………
INTERSECT
SELECT * FROM table2 WHERE………
19
Opérateurs ensemblistes
Opérateur EXCEPT
• permet d'ôter d'une sélection les lignes obtenues dans une
deuxième sélection.
Syntaxe: (les deux tables ont le même schéma)
SELECT * FROM table1 WHERE …
EXCEPT
SELECT * FROM table2 WHERE…
20
Produit cartésien (normeSQL2)
• La norme SQL2 a aussi une syntaxe
spéciale pour le produit cartésien de deux
tables :
• Exemple:
SELECT Nomemp, nomdep
FROM employe CROSS JOIN
departement
21
Jointure (norme SQL2):
Liste des noms d’employés avec le nom du
département où ils travaillent :
SELECT nomemp, nomdep
FROM employe JOIN departement
ON employe.coddep =
departement.coddep
22
Jointure: ancienne notation
• La jointure peut aussi être traduite par la clause WHERE :
SELECT nomemp, nomdep
FROM employe , departement
WHERE employe.coddep =departement.coddep
• Cette façon de faire est encore très souvent utilisée, même
avec les SGBD qui supportent la syntaxe SQL2.
23
Jointure naturelle
Syntaxe:
SELECT Nomemp, nomdep
FROM employe NATURAL JOIN departement
REMARQUES:
• on n'a pas besoin d'indiquer les colonnes de jointure car la
clause natural join joint les deux tables sur toutes les
colonnes qui ont le même nom dans les deux tables.
• Si on utilise une jointure naturelle, il est interdit de préfixer
une colonne utilisée pour la jointure par un nom de table.
La requête suivante provoque une erreur :
SELECT Nomemp, nomdep, departement.coddep
FROM employe NATURAL JOIN departement
24
Jointure naturelle (suite)
• Il faut écrire :
SELECT Nomemp, nomdep, coddep
FROM employe NATURAL JOIN departement
• Comment obtenir la jointure naturelle sur une partie
seulement des colonnes qui ont le même nom?
il faut utiliser la clause _ join using_ (s'il y a plusieurs
colonnes, le séparateur de colonnes est la virgule).
• La requête suivante est équivalente à la précédente :
SELECT nomemp, nomdep
FROM employe JOIN departement USING coddep
25
Jointure d'une table avec elle-même
• Il peut être utile de rassembler des informations
provenant d'une ligne d'une table avec des
informations venant d'une autre ligne de la même
table.
• Dans ce cas il faut renommer au moins l'une des
deux tables en lui donnant un synonyme , afin de
pouvoir préfixer sans ambiguïté chaque nom de
colonne.
26
Jointure d'une table avec elle-même
• Lister les employés qui ont un supérieur, en indiquant pour
chacun le nom de son supérieur :
SELECT employe.nomemp employe, supe.nomemp
superieur
FROM employe join employe supe
on employe.superieur = supe.codemp
ou
SELECT employe.nomemp employe, supe.nomemp superieur
FROM employe, employe supe
WHERE employe.superieur = supe.codemp
27
Jointure non-équi
• Les jointures autres que les équi-jointures
(inéqui-jointures) peuvent être
représentées :
• En remplaçant dans la clause ON
ou la clause WHERE le signe = par un
des opérateurs de comparaison (<, <=,
>, >=, !=), ou encore between et in.
28
Sous-interrogation
• Une caractéristique puissante de SQL est la possibilité
qu'un prédicat employé dans une clause WHERE comporte
un SELECT emboîté.
• Exemple: Quels sont les employés ayant le même
département que l’employé de code 123:
1ère solution: avec la jointure:
SELECT employe.nomemp
FROM employe JOIN employe E2
ON employe.coddep= E2.coddep
WHERE E2.codemp = 123
AND employe. Codemp!= E2. codemp
29
Sous-interrogation
Exemple:
Quels sont les employés ayant le même
département que l’employé de code 123:
2ère solution: avec la sous-interrogation:
SELECT nomemp
FROM employe
WHERE coddep = (SELECT coddep
FROM employe
WHERE codemp = 123)
And codemp != 123
30
Sous-interrogation à une ligne et une colonne
• Dans ce cas, le SELECT imbriqué équivaut
à une valeur.
Syntaxe: WHERE exp op (SELECT ...)
où :
• op est un des opérateurs = !=, <, >,
<= , >=
• exp est toute expression légale
Revoir Exemple prédédent
31
Sous-interrogation ramenant plusieurs lignes
• Une sous-interrogation peut ramener plusieurs
lignes :
• Les opérateurs permettant de comparer une
valeur à un ensemble de valeurs sont :
l'opérateur IN
ANY ou ALL à la suite des opérateurs de
comparaison: (=, !=, <, >, <=, >=)
• Forme de la sous-requête:
WHERE exp op ANY (SELECT ...)
WHERE exp op ALL (SELECT ...)
WHERE exp IN (SELECT ...)
WHERE exp NOT IN (SELECT ...)
32
Sous-interrogation ramenant plusieurs lignes: les opérateurs ANY et ALL
WHERE exp op ANY (SELECT ...)
ANY : la comparaison sera vraie si elle est
vraie pour au moins un élément de
l'ensemble (elle est donc fausse si
l'ensemble est vide).
WHERE exp op ALL (SELECT ...)
ALL : la comparaison sera vraie si elle est
vraie pour tous les éléments de l'ensemble
(elle est vraie si l'ensemble est vide).
33
Sous-interrogation ramenant plusieurs lignes: les opérateurs ANY et ALL
Exemple:
Liste des employés gagnant plus que tous les employés du
département 30 :
SELECT nomemp, salaire
FROM employe
WHERE salaire > ALL
(SELECT salaire FROM employe
WHERE coddep=30)
Remarques:
L'opérateur IN est équivalent à = ANY
l'opérateur NOT IN est équivalent à != ALL.
34
Sous-interrogation ramenant plusieurs lignes
Exemple :
Liste des employés du département 10 ayant le même poste
que quelqu'un du département VENTES :
SELECT nomemp, codposte
FROM employe
WHERE coddep = 10
AND codposte = ANY {or codposte in(……..))}
(SELECT codposte
FROM employe
WHERE coddep =
(SELECT coddep
FROM departement
WHERE nomdep = 'VENTES'))
35
Fonctions de groupes
(1)
Fonction Rôle
AVG Moyenne
MIN Plus petite valeur
SUM Somme
MAX Plus grande valeur
VARIANCE Variance
Count(*) Nombre de lignes
Count(DISTINCT col) Nombre de valeurs non nulles
différentes
Count(col) Nombre de valeurs non nulle de
la colonne col
STDDEV Écart type(dérivation standard)
36
Fonctions de groupes
(2)
Exemples:
• Nombre total des employés en service?
SELECT COUNT(*)
FROM employe
• Valeur globale des primes des employés du département
1O?
SELECT SUM(prime)
FROM employe
WHERE coddep = 10
37
Fonctions de groupes
(3)
Les fonctions de groupes peuvent apparaître dans
le « Select » ou le «Having »
• Les valeurs NULL sont ignorées par les fonctions
de groupe.
▫ SUM(col) est la somme des valeurs différentes
de NULL de la colonne 'col'.
▫ AVG : (somme des valeurs non NULL )/
( nombre de valeurs non NULL).
38
Fonctions de groupes et sous-interrogations du
SELECT
• Les fonctions de groupe et les colonnes doivent être toutes
du même niveau de regroupement.
Q) le nom et le salaire des employés qui gagnent le plus dans
l'entreprise?
Requête erronée
SELECT nom_emp, salaire FROM employe
WHERE salaire = MAX(salaire)
Requête correcte
utiliser une sous-interrogation
SELECT nom_emp, salaire FROM employe
WHERE salaire = (SELECT MAX(salaire) FROM employe)
39
Clause GROUP BY
syntaxe
SELECT [Ai1] [,Ai2]….[,Ain] [F1(Aj1)] ,[F2(Aj2)] , … ,
[Fv(Ajv)]
FROM < expression de tables>
[WHERE < condition de recherche>]
GROUP BY Ak1 ,[Ak2], … ,[Akw]
[HAVING < condition de groupe >]
avec :
• Fi = fonction de calcul (COUNT, AVG, SUM, MAX,
…)
• et {Ak1, Ak2,…., Akw} {Ai1, Ai2, …., Ain}
• et {Ak1, Ak2,…., Akw} {Aj1, Aj2,…., Ajv} =
40
Clause GROUP BY
exécution
Exécuter la clause ‘FROM <expression de tables>
Si le ‘WHERE’ existe, sélectionner les lignes qui vérifient le prédicat
Exécuter le ‘GROUP BY’ qui répartit les lignes dans des groupes où les colonnes du
group by ont toutes la même valeur. Les ‘NULL’ sont traités comme s’ils étaient égaux
entre eux, et forment donc leur propre groupe.
Appliquer les fonctions de calcul spécifiées dans la clause SELECT sur les groupes
générés. Chaque groupe est alors réduit à une seule ligne dans une nouvelle table de
résultats.
S’il y a une clause ‘HAVING’, elle s’applique à tous les groupes. Les groupes pour
lesquels le test donne ‘true’ sont retenus, ceux qui donnent ‘false’ ou ‘unknown’ sont
supprimés.
41
Clause GROUP BY
Rôle:
Subdiviser la table en groupes, chaque groupe
contient l'ensemble des lignes ayant la même
valeur
GROUP BY exp1, exp2,... :
groupe en une seule ligne toutes les lignes
pour lesquelles exp1, exp2,... ont la même
valeur.
Group By se place :
▫ juste après la clause WHERE
▫ après la clause FROM si la clause WHERE
n'existe pas.
42
Clause GROUP BY:
exemples
• Afficher le nombre d’employés de chaque
département
SELECT coddep, COUNT(*)
FROM employe
GROUP BY coddep
• Afficher le nombre de secrétaires de chaque
département
SELECT coddep, COUNT(*)
FROM employe
WHERE codposte = 'SECR'
GROUP BY coddep
43
Clause GROUP BY:
exemples
afficher le nombre d’employés occupant le même poste dans
chaque département:
SELECT coddep, codposte, COUNT(*)
FROM employe
GROUP BY coddep, codposte
44
Clause GROUP BY :
RESTRICTION
• Une expression d'un SELECT avec clause GROUP
BY doit correspondre à une caractéristique de
groupe.
• Le SELECT contient :
▫ soit une fonction de groupe,
▫ soit une expression figurant dans le GROUP
BY.
• Exemple de requête erronée :
( nomdep ne figure pas dans le GROUP BY)
SELECT nomdep , SUM(salaire)
FROM employe NATURAL JOIN departement
GROUP BY coddep
45
Clause GROUP BY:
Restriction
Il faut, soit se contenter du numéro de département au lieu
du nom :
SELECT coddep, SUM(salaire)
FROM employe NATURAL JOIN departement
GROUP BY coddep
ou bien:
SELECT nomdep, SUM(salaire)
FROM employe NATURAL JOIN departement
GROUP BY nomdep
46
Clause HAVING
• Prédicat qui sert à préciser quels groupes doivent
être sélectionnés.
• Elle se place après la clause GROUP BY.
• HAVING suit la même syntaxe que le WHERE.
• Il ne peut porter que sur des fonctions de groupe
ou des expressions figurant dans la clause
GROUP BY.
47
Clause HAVING
Exemple
o Afficher les départements qui comptent plus d’une
secrétaire:
SELECT coddep, COUNT(*) “nombre_secr”
FROM employe
WHERE codposte = 'SECR'
GROUP BY coddep
HAVING nombre_secr >1;
48
Clause HAVING
Possibilité de combiner toutes les clauses, des jointures et
des sous-interrogations.
Exemple:
Donner le nom du département (et son nombre de
secrétaires) qui a le plus de secrétaires :
SELECT nomdep as Departement, COUNT(*) as Nombre de
secretaires
FROM employe NATURAL JOIN departement
WHERE codposte = 'SECR'
GROUP BY nomdep
HAVING COUNT(*) = (SELECT MAX(COUNT(*)) FROM
employe
WHERE POSTE = 'SECR'
GROUP BY coddep)
49
ORDER BY :
Exemples
Liste des valeurs globales de salaires par département triée
par ordre croissant:
SELECT coddep, SUM(salaire) "Total salaires" FROM
employe
GROUP BY coddep
ORDER BY 2
SELECT coddep, SUM(salaire) "Total salaires" FROM
employe
GROUP BY coddep
ORDER BY SUM(salaire)
SELECT coddep, SUM(salaire) "Total salaires" FROM
employe
50
Opérateur EXISTS
• La clause EXISTS est suivie d'une sous-
interrogation entre parenthèses (select…)
• EXISTS prend la valeur vrai s'il existe au moins
une ligne satisfaisant les conditions de la sous-
interrogation.
• Souvent on peut utiliser IN à la place de la
clause EXISTS
51
Opérateur EXISTS
exemple
• Exemple:
afficher le nom des départements qui ont au moins un employé
ayant plus de 40.000 comme salaire
SELECT nomdep
FROM departement
WHERE EXISTS
(SELECT * FROM employe
WHERE employe.coddep = departement.coddep
AND salaire >40000);
• pour chaque ligne de la table ‘departement’ la sous-interrogation
est exécutée et si au moins une ligne est trouvée dans la table
‘employe’, EXISTS prend la valeur vrai et la ligne de
‘departement’ satisfait les critères de l'interrogation.
52
Fin de la partie SQL-LID
(SELECT)
Prochaine section : SQL-LMD
SQL-LDD