Dans ce chapitre ...
SQL
Du langage algébrique à SQL
La machine SQL I
les relations de Hotel
exemples de translation L.A. en SQL
select-commande
displayed column, selected-table
Expression
condition de la clause WHERE
appartenance à une chaine de caractères
appartenance à un intervalle
comparaison avec la valeur null
Prédicats quantifiés
jointure externe
Les sous-requêtes
Machine SQL II (sous-requête)
Regroupements
Machine SQL III (regroupement)
Opérateurs Ensemblistes
Hiérarchie
Ordonner le résultat
Machine SQL IV
SQL
Plan de
Langage
d'interrogation (SQL)
SQL = Structured Query Language
Une norme ISO
SQL - 1986 niveau I
SQL - 1989 niveau II
SQL 2 - 1992
SQL 3 - 1995-96 ?
Existe sur tous les SGBD relationnels (plus ou moins proche de la norme)
Du langage algébrique à SQL
Plan de
Langage
d'interrogation (SQL)
La relation R
R = select * from R
La projection R[X] où X={C1, C2, ..., Cn}
R[X] = select C1, C2, ..., Cn from R
La sélection (*F)R
(*F)R = select * from R where F
Le produit R ** S
R** S = select R.*,S.* from R,S
La composition R * S où R
S
={C1, C2, ..., Cn}
R* S = select R.*,S.* from R,S
where R.C1 = S.C1
and R.C2 = S.C2
...
and R.Cn = S.Cn
L'union (intersection, différence) R
S
R
S = select * from R union select * from S
(*F) R1 * R2 * ... * Rn [C1, C2, ..., Cm]
= select C1, C2, ..., Cm
from R1, R2, ... , Rn
where F and Composition
La machine SQL I
Plan de
Langage
d'interrogation (SQL)
-faire le produit cartésien de toutes les relations citées après le FROM
-sélectionner les entités satisfaisant la condition décrite après WHERE
-projeter sur les constituants cités après le SELECT

Modèle I, modèle simplifié de la machine SQL
les relations de Hotel
Plan de
Langage
d'interrogation (SQL)
SELECT * FROM CHAMBRES . NUM_CHAMBRE PRIX NBR_LITS NBR_PERS CONFOR EQU ----------- ---------- ---------- ---------- ------ --- 10 80 1 2 WC NON 20 80 1 2 WC NON 30 80 1 2 WC NON 40 80 1 2 WC NON 11 90 2 2 WC NON 21 90 2 2 WC NON 31 90 2 2 WC NON 41 90 2 2 WC NON 12 100 2 2 DOUCHE NON 22 100 2 2 DOUCHE NON 32 100 2 2 DOUCHE NON 42 100 2 2 DOUCHE NON 13 120 1 2 BAIN NON 23 120 1 2 BAIN NON 33 120 1 2 BAIN NON 43 120 1 2 BAIN NON 14 140 2 2 BAIN TV 24 140 2 2 BAIN TV 34 140 2 2 BAIN TV 44 140 2 2 BAIN TV 15 180 3 4 BAIN TV 25 180 3 4 BAIN TV 35 180 3 4 BAIN TV 45 180 3 4 BAIN TV.
SELECT * FROM CLIENTS . NUM_CLIENT NOM PRENOM ADRESSE ---------- ---------- ---------- -------------------------------- 1000 GASCON GASTON 12 av. du Général 1239 ICI 1001 DUPONT PIERRE 12 ch. des hirondelles 1238 LABAS 1002 DUFOUR JEAN 10 av. de la gar 1300 AILLEURS 1003 ZORO DIEGO 10 ch des voleurs Los Angeles 1004 EINSTEIN ALBERT 10 route de la relativité 1004 PLUS-LOIN 1005 DUMAS ALEXANDRE 10 route du moulins LE-SUD 1007 NOBODY FRANCOISE 403 route de l inconnu 75000 Paris 1006 ROMULUS BERNADETTE 241 route de rome 1409 Lion 1009 AGDA BRUNO 10 route de l impossible 1508 TEXAS 1008 CHADOK AMELIE 25 rue de la rame 1456 Tombouctou.
SELECT * FROM RESERVATIONS . NUM_CLIENT NUM_CHAMBRE DATE_ARR DATE_DEP ---------- ----------- --------- --------- 1000 11 11-JAN-90 15-JAN-90 1001 21 10-JAN-90 1002 34 20-DEC-89 27-DEC-89 1003 44 24-DEC-89 27-DEC-89 1005 45 23-DEC-89 28-DEC-89 1006 14 01-DEC-89 28-DEC-89 1007 23 01-DEC-89 02-DEC-89 1007 23 08-DEC-89 09-DEC-89 1007 23 15-DEC-89 16-DEC-89 1007 23 22-DEC-89 23-DEC-89 1007 23 29-DEC-89 30-DEC-89.

(* ((Confort=bain)
(Equipement=TV)) Chambres
En SQL
Select * from Chambres where Confort='bain' and Equipement='TV' . NUM_CHAMBRE PRIX NBR_LITS NBR_PERS CONFOR EQU ----------- ---------- ---------- ---------- ------ --- 14 140 2 2 BAIN TV 24 140 2 2 BAIN TV 34 140 2 2 BAIN TV 44 140 2 2 BAIN TV 15 180 3 4 BAIN TV 25 180 3 4 BAIN TV 35 180 3 4 BAIN TV 45 180 3 4 BAIN TV.
(Chambres [NumChambre, NbrPers])
En SQL
Select NumChambre, NbrPers from Chambres . NUM_CHAMBRE NBR_PERS ----------- ---------- 10 2 20 2 30 2 40 2 11 2 21 2 31 2 41 2 12 2 22 2 32 2 42 2 13 2 23 2 33 2 43 2 14 2 24 2 34 2 44 2 15 4 25 4 35 4 45 4.
(* ((DateArr <= 25-12-89)
(DateDep >25-12-89))
(Clients * Réservation))[Nom]
En SQL
Select nom
from Clients,Réservation
where DateArr <= date('25-12-89')
and DateDep > date('25-12-89')
and Clients.numclient = Réservation.numclient
.
NOM
--------------------
DUFOUR
ZORO
DUMAS
ROMULUS .
((Clients * Réservation) * Chambres)[Nom, Confort]
En SQL
Select Nom, Confort from Clients, Réservation, Chambres where Clients.numclient = Réservation.numclient and Chambres.numchambre=Réservation.numchambre . NOM CONFOR -------------------- ------ GASCON WC ROMULUS BAIN DUPONT WC NOBODY BAIN NOBODY BAIN NOBODY BAIN NOBODY BAIN.
pas exprimable en langage algébrique
En SQL
Select sum(nbpers) from Chambres . SUM(NBR_PERS) ------------- 56.

select-command

distinct élimination des doublons (implique un tri)
* tous les cst de toutes les relation de la cause FROM
SELECT confort,equipement -- les types de chambres FROM CHAMBRES . CONFOR EQU ------ --- WC NON WC NON WC NON WC NON WC NON WC NON WC NON WC NON DOUCHE NON DOUCHE NON DOUCHE NON DOUCHE NON BAIN NON BAIN NON BAIN NON BAIN NON BAIN TV BAIN TV BAIN TV BAIN TV BAIN TV BAIN TV BAIN TV BAIN TV.
SELECT distinct confort,equipement FROM CHAMBRES . CONFOR EQU ------ --- BAIN NON BAIN TV DOUCHE NON WC NON.
selected-table : permet de spécifier les relations impliquées dans la requête
Condition : permet de spécifier la condition de sélection
Connect-Clause : permet de spécifier un parcours arborescent
Group-Clause : permet de spécifier les regroupements
Set-Clause: permet de spécifier les opérations ensemblistes
Order-Clause : permet de spécifier les critères de tri sur le résultat
Update-Clause: permet de spécifier les critères de verrouillage pour la concurrence
displayed column, selected-table
Plan de
Langage
d'interrogation (SQL)

table-name.* : tous les constituants de la relation (dans l'ordre de déclaration)
expression :
- table-name.cst (si il existe une ambiguïté)
- cst
- fct(...) ( par exemple sum(nbpers))
- expression de calcul (x/y*100)
SELECT * FROM CHAMBRES
SELECT CHAMBRES.* FROM CHAMBRES
SELECT HOTEL.CHAMBRES.* FROM CHAMBRES
sont équivalentes
Le prix par personne des chambres ayant une TV ?
SELECT num_chambre "Numéro de Chambre", prix/nbr_pers "prix par pers" FROM Chambres WHERE equipement='TV' . Numéro de Chambre prix par pers ----------------- ------------- 14 70 24 70 34 70 44 70 15 45 25 45 35 45 45 45.

table-name : nom des relations utilisées dans la requête
alias : permet de renommer une relation (nom plus court, un autre nom dans le cas où une relation est utilisée deux fois)
les chambres ayant le même confort et le même équipement qu'une autre chambre mais ayant un prix inférieur de 10% à celle-ci"
SELECT distinct c1.num_chambre FROM CHAMBRES c1, CHAMBRES c2 WHERE c1.confort=c2.confort AND c1.equipement=c2.equipement AND c1.prix*1.1<c2.prix . NUM_CHAMBRE ----------- 10 14 20 24 30 34 40 44.

Une expression est un terme ou une suite de termes connectés par les opérateursarithmétiques + ou -
Expression

Terme
Un terme est un facteur ou une suite de facteurs connectés par les opérateurs arithmétiques * ou /.

Facteur

- la variable qui est un nom de colonne. Eventuellement préfixée par le nom de la table, dans le cas où ce nom appartient à plusieurs tables manipulées dans une même requête (numchambre, Chambres.numchambre).
- une fonction avec ses paramètres d'appel: power(taux_annuel, nombre_annees). Les fonctions disponibles dépendent du SGBD utilisé. Nous donnons en annexe un apperçu de l'étendue de celles-ci.
- une fonction de regroupement avec ses paramètres d'appel: count(*), avg(prix/nbpers). Nous donnons une explication détaillée dans la clause de regroupement.
- une expression entre parenthèses afin d' ôter les
ambiguïtés: (a+b)*(c+d)
condition de la clause WHERE
Plan de
Langage
d'interrogation (SQL)
une condition est un prédicat exprimé sur les rangées du
produit cartésien


les chambres coûtants au max. 80 francs ou ayant un bain et valant au max. 120
SELECT num_chambre, prix, confort FROM CHAMBRES WHERE (prix<=80) OR ((confort='BAIN') AND (prix<=120)) . NUM_CHAMBRE PRIX CONFOR ----------- ---------- ------ 10 80 WC 20 80 WC 30 80 WC 40 80 WC 13 120 BAIN 23 120 BAIN 33 120 BAIN 43 120 BAIN.

- une comparaison entre deux expressions (=,>,<, ...)
- un test d'appartenance à un ensemble (in)
- un test d'appartenance à une chaîne de caractères (like)
- un test d'appartenance à un intervalle (between).
- une comparaison avec la valeur null
- un prédicat quantifié(exists, all, any)
- une condition entre parenthèses afin d'ôter les ambiguïtés.
exp1 < exp2 ;exp1 est strictement inférieur à exp2
exp1 <= exp2 ;exp1 est inférieur ou égal à exp2
exp1 > exp2 ;exp1 est strictement supérieur à exp2
exp1 >= exp2 ;exp1 est supérieur ou égal à exp2
exp1 <> exp2 ;exp1 est différent de exp2 (aussi noté != ou ^=)
table pour l'évaluation du null pour =
exp1/exp2 !=null =null !=null vrai ou faux faux =null faux faux
=> tester le null avec la clause is null

exp-set

énumémer explicitement les éléments
Exp1 in (c1,c2,c3, ... cn)
(Exp1 = c1) AND (Exp1 = c2) AND ...(Exp1 = cn)
définir les éléments par une sous-requête
SELECT num_chambre FROM CHAMBRES
WHERE confort in ('BAIN','DOUCHE')
.
NUM_CHAMBRE
-----------
12
22
32
42
13
23
33
43
14
24
34
44
15
25
35
45.Recette du 25-décembre-1989
SELECT sum(prix) FROM Chambres Ch WHERE num_chambre in (SELECT num_chambre FROM Reservations R WHERE date_arr<='25-dec-89' AND date_dep>'25-dec-89') SUM(PRIX) ---------- 600.

On test ici si une chaîne de caractères ressemble à un "patron"
% qui est substituable à n'importe quelle chaîne de caractères y compris la chaîne vide.
_ (souligné) est substituable à un seul caractère

Nom du client commençant par "DU"
SELECT nom FROM CLIENTS WHERE Nom like 'DU%' . NOM -------------------- DUPONT DUFOUR DUMAS.
Nom du client ayant un "0" pour quatrième lettre
SELECT nom FROM CLIENTS WHERE Nom like '___O%' . NOM -------------------- DUPONT DUFOUR ZORO NOBODY.

between est une facilité d'écriture
exp1 between exp2 AND exp3
(exp2 <= exp1) AND (exp1 <= exp3)
nombre de chambres dont le prix est entre 85 et 120 francs
SELECT count(num_chambre) FROM CHAMBRES WHERE prix between 85 AND 120 . COUNT(NUM_CHAMBRE) ------------------ 12.

tester si une expression est indéfinie
exp1 exp1 is null !=null faux =null vrai
not (exp1 is null)
exp1 is not null
Clients n'ayant pas fixé leur date de départ
SELECT Nom FROM ClIENTS, RESERVATIONS WHERE ClIENTS.num_client=RESERVATIONS.num_client AND date_dep is null . NOM -------------------- DUPONT.


exists permet de tester s'il existe au moins une rangée correspondant au prédicat de la sous-requête
Exists (SELECT 'Vrai' FROM .... WHERE ...)
all permet de tester si toutes les rangées, correspondant au prédicat de la sous-requête, vérifient une certaine condition
Exp1
all (SELECT col1 FROM ... WHERE ...)
(Exp1
c1) AND (Exp1
c2) AND
...(Exp1
cn)
any permet de tester si au moins une rangée, correspondant au prédicat de la sous-requête, vérifie une certaine condition
Exp1
any (SELECT col1 FROM ... WHERE ...)
(Exp1
c1) OR (Exp1
c2) OR
...(Exp1
cn)
Exp1 in (SELECT col1 FROM ... WHERE ...)
Exp1 = any (SELECT col1 FROM ... WHERE ...)
on a
x, (P(x))
~
x, (~P(x))
Exp1
all (SELECT col1 FROM ... WHERE ...)
not Exists (SELECT 'Vrai' FROM ....
WHERE ... AND not(exp1
col1))
jointure externe
Plan de
Langage
d'interrogation (SQL)
afficher tous les numéros de chambre et le numéro du client ayant réservé la chambre pour le 25-décembre-1989.
SELECT Ch.num_chambre, num_client FROM Chambres Ch,Reservations R WHERE Ch.num_chambre=R.num_chambre AND date_arr<='25-dec-89' AND date_dep>'25-dec-89' . NUM_CHAMBRE NUM_CLIENT ----------- ---------- 14 1006 34 1002 44 1003 45 1005.
On a que les chambres réservées...
En postfixant les colonnes d'une table par (+), on spécifie une jointure externe.
Si aucune rangée de la table ne satisfait les conditions de sélection, alors le SGBD met des valeurs null pour les colonnes de cette table.
afficher tous les numéros de chambre et le numéro du client ayant réservé la chambre pour le 25-décembre-1989.SELECT Ch.num_chambre, num_client FROM Chambres Ch,Reservations R WHERE Ch.num_chambre=R.num_chambre(+) AND date_arr(+)<='25-dec-89' AND date_dep(+)>'25-dec-89' . NUM_CHAMBRE NUM_CLIENT ----------- ---------- 10 11 12 13 14 1006 15 20 21 22 23 24 25 30 31 32 33 34 1002 35 40 41 42 43 44 1003 45 1005.


une sous requête permet de définir un ensemble d'entités, il est à utiliser dans les cas suivants:
- pour insérer, ou initialiser une relation (Insert, Create, Copy)
- pour définir l'étendue d'une modification (Update, Delete)
- pour permettre des comparaisons (where, having, start with)
- condition exprimée par une requête
prix moyen des chambres ayant le même confort que celle du client No 234 ?
SELECT avg(prix) FROM Chambres WHERE Confort = (SELECT Confort FROM Chambres, Reservations WHERE Chambres.num_chambre=Reservations.num_chambre AND num_client=1006) . AVG(PRIX) ---------- 146.666667.
La sous-requête est imbriquée dans une autre requête. Dans une sous-requête, on peut faire référence à des variables définies à un niveau supérieur. Il faut alors les considérer comme des paramètres qui sont modifiés pour chaque rangée du produit cartésien du niveau supérieur.
exemple: chambre ayant un prix 10% inférieur à la moyenne pour une même catégorie de confort
SELECT Num_chambre,confort FROM Chambres a WHERE prix < (SELECT avg(prix)*0.90 FROM Chambres b WHERE b.confort=a.confort) . NUM_CHAMBRE CONFOR ----------- ------ 13 BAIN 23 BAIN 33 BAIN 43 BAIN.


Regroupements
Plan de
Langage
d'interrogation (SQL)

Cette clause permet de spécifier le regroupement d'un certain nombre d'entités selon un critère. Le résultat ne donne donc qu'une seule entité.
- avg : calculer la moyenne d'une liste
- Count : dénombrer les éléments d'une liste
- min : déterminer l'élément minimum d'une liste
- max : déterminer l'élément maximum d'une liste
- sum : calculer la somme d'une liste
La Clause Having permet de spécifier un critère sur les entités regroupées (La clause where permet de spécifier le critère sur les entités intervenant dans le regroupement)
Prix moyen des chambres par type de confort:
SELECT Confort,AVG(Prix) "prix moyen" FROM Chambres Group by Confort . CONFOR prix moyen ------ ---------- BAIN 146.666667 DOUCHE 100 WC 85.
Prix minimum et maximum des chambres par type de confort:
SELECT Confort,Min(Prix),Max(Prix) FROM Chambres Group by Confort . CONFOR MIN(PRIX) MAX(PRIX) ------ ---------- ---------- BAIN 120 180 DOUCHE 100 100 WC 80 90.
Prix minimum et maximum des chambres par type de confort, mais dont le prix Min est plus petit que 100:
SELECT Confort,Min(Prix),Max(Prix) FROM Chambres Group by Confort Having Min(Prix)<100 . CONFOR MIN(PRIX) MAX(PRIX) ------ ---------- ---------- WC 80 90 .


Celui-ci est effectué sur les rangées qui sont sélectionnées par la clause WHERE.
L'expression de regroupement doit être équivalente à toutes les expressions comportant des variables apparaissant dans le résultat. (superflu!)
Le processus de regroupement intervenant après la sélection des rangées.
La clause having permet de spécifier le critère sur les entités regroupées.
La clause WHERE permet de spécifier le critère sur les
entités intervenant dans le regroupement
Opérateurs Ensemblistes
Plan de
Langage
d'interrogation (SQL)

Union, Intersect, Minus (Différence) ont le sens habituel.
Les relations (opérandes) de ces opérateurs doivent avoir la même arité (nbr de constituants) et les constituants doivent être égaux en type (pas forcément en taille).
Les termes employés pour une chambre
SELECT confort "Termes" FROM CHAMBRES union SELECT equipement FROM CHAMBRES . Termes ------ BAIN DOUCHE NON TV WC.
L'utilisation de ces opérateurs implique implicitement la clause
DISTINCT, donc l'élimination des "doublons".
Hiérarchie
Plan de
Langage
d'interrogation (SQL)

Cette clause permet de parcourir une relation en fixant un ordre hiérarchique (arbre)
La clause PRIOR doit être utilisée pour fixer la relation parent-enfant pour le parcours de l'arbre (la profondeur maximum de l'arbre est limitée à 256). Le coté gauche définit le parent et le coté droite l'enfant.
La clause START WITH définit la racine de l'arbre (ou les racines)
"||Personnes(a,b,c)|| La personne, portant le numéro b et se nommant a a un manager portant le numéro c"
NOM NUM_EMP NUM_MANAGER SALAIRE ------------ ---------- ----------- ---------- DOMINIQUE 1 10000 MARIE 2 1 6000 JEAN 3 1 5000 PAUL 4 2 5000 MARTINE 5 2 5000 VINCENT 6 4 5500 HENRI 7 4 4000 MADELEINE 8 3 4000 ANNE 9 3 3000.
établir une liste des noms de personne par ordre hiérarchique.
SELECT lpad('-',3*level)||Nom "Hiérarchie"
FROM EMP
Connect by prior Num_Emp=Num_Manager
Start with Num_Manager is NULL
.
Hiérarchie
---------------------------
-DOMINIQUE
-MARIE
-PAUL
-VINCENT
-HENRI
-MARTINE
-JEAN
-MADELEINE
-ANNE.
La fonction level indique le niveau d'un noeud dans l'arborescence.
La fonction lpad permet d'insérer des blancs à gauche (cadrer à droite)
SELECT Nom FROM EMP E1 WHERE .i.exists ;(SELECT * FROM EMP E2 WHERE E1.num_emp=E2.num_manager) . NOM ------------ DOMINIQUE MARIE JEAN PAUL.
Qui est chef d'un employé mieux payé que lui-même?
SELECT Nom FROM EMP E1 WHERE E1.salaire< any (SELECT salaire FROM EMP E2 WHERE E1.num_emp=E2.num_manager) . NOM ------------ PAUL.
Qui est Chef "absolu", aucun employé mieux payé que lui-même ?
SELECT Nom FROM EMP E1 WHERE exists (SELECT * FROM EMP E2 WHERE E1.num_emp=E2.num_manager) AND E1.salaire> all (SELECT salaire FROM EMP E2 WHERE E1.num_emp=E2.num_manager) . NOM ------------ DOMINIQUE MARIE JEAN.

Order-Clause

Cette Clause permet de trier une relation afin de l'afficher dans un ordre donné. Donc seule la représentation externe est affectée par ce tri.
Sorted-def

- expression : est une expression de la clause select
- position : est un nombre indiquant le numéro de la colonne à trier. Ce type de spécification du critère de tri est obligatoire dans le cas où le résultat est obtenu par utilisation d'un opérateur ensembliste (en effet les colonnes proviennent de requêtes différentes)
- asc : par ordre croissant (par défaut)
- desc : par ordre décroissant
SELECT nom, adresse FROM Clients Order by nom asc . NOM ADRESSE -------------------- ---------------------------------------- AGDA 10 route de l impossible 1508 TEXAS CHADOK 25 rue de la rame 1456 Tombouctou DUFOUR 10 av. de la gar 1300 AILLEURS DUMAS 10 route du moulins LE-SUD DUPONT 12 ch. des hirondelles 1238 LABAS EINSTEIN 10 route de la relativité 1004 PLUS-LOIN GASCON 12 av. du Général 1239 ICI NOBODY 403 route de l inconnu 75000 Paris ROMULUS 241 route de rome 1409 Lion ZORO 10 ch des voleurs Los Angeles.
Exemples avec TT3
Les relations d'une opération ensembliste sont calculées indépendament.
Le tri est effectué en dernier sur le résultat final.
