SQL :
Structured Query
Langage
2
SQL: Trois langages
Langage de définition de données (LDD/DDL)
création de relations : CREATE TABLE modification de relations: ALTER TABLE suppression de relations: DROP TABLE vues, index …. : CREATE VIEW ...
Langage de requêtes (LMD/DML)
SELECT ….... FROM ... WHERE ...
Langage de manipulation de données (LMD /DML)
insertion de tuples: INSERT
mise à jour des tuples: UPDATE suppression de tuples: DELETE
SQL : partie langage
de requêtes
4
Structure générale d’une requête :
le BLOC
Structure d'une requête formée de trois clauses:
SELECT <liste-attributs> FROM <liste-tables>
WHERE <condition>
SELECT définit le format du résultat cherché
FROM définit à partir de quelles tables le résultat
est calculé
WHERE définit les prédicats de sélection du
Exemple de requête
SELECT * FROM country
->
tous les attributs de tous les tuples dans la table “country” country Ireland Austria Utd Kingdom Switzerland capital Dublin Vienna London Berne population area 3 70 8 83 56 244 7 41 table CountrySQL/Algèbre
Passage de l ’algèbre relationnelle au
langage de requêtes de SQL
Traduction de chacun des 9 opérateurs en
8
SQL / Algèbre … Identité
En algèbre :
Id(R)
En SQL :
SELECT *
FROM R
SQL / Algèbre … Sélection
En algèbre :
σ[condition] R
En SQL :
SELECT *
FROM R
WHERE condition
10
Exemple de requête de sélection
Irlande Dublin 3 70
Autriche Vienne 8 83
Royaume-Uni Londres 36 244
Suisse Berne 7 41
USA Washington 189 441
nom capitale population surface
PAYS
* = toutes les colonnes
SELECT *
FROM Pays
WHERE
population < 20 ;
algèbre:SQL / Algèbre … Projection
En algèbre :
π
[ A1, A2,…, An] R
En SQL :
SELECT A1,A2,…An
FROM R
12
Exemple de requête de projection
SELECT nom,
capitale
FROM Pays;
Irlande Dublin 3 70 Autriche Vienne 8 83 Royaume-Uni Londres 36 244 Suisse Berne 7 41 USA Washington 189 441nom capitale population surface
PAYS
Requête de sélection + projection
Irlande Dublin 3 70 Autriche Vienne 8 83 Royaume-Uni Londres 36 244 Suisse Berne 7 41 USA Washington 189 441nom capitale population surface
PAYS
Irlande Dublin 3 Autriche Vienne 8
Suisse Berne 7
nom capitale population résultat
SELECT nom, capitale, population
FROM Pays WHERE population < 20 ;
14
SQL / Algèbre … Renommage
En algèbre :
α (A1/B1, ..., An/Bn) R
En SQL : Impossible de
renommer des attributs. Il faut faire des “copies
logiques” des relations. SELECT *
FROM R, R R2
WHERE R.A = R2.A ….
R2 peut être vue comme
SQL / Algèbre … Produit cartésien
En algèbre :
R × S
En SQL :
SELECT *
FROM R, S
16
SQL / Algèbre … Jointure
En algèbre :
R S
En SQL : SELECT * FROM R, SWHERE R.A1 = S.A1 AND R.A2 = S.A2
…
AND R.An = S.An
Avec A1, …, An tous les
Jointure de 2 relations
SELECT année, lieu, pays, capitale
FROM JO, PAYS
WHERE JO.pays =PAYS.nom;
Irlande Dublin 3 70
Autriche Vienne 8 83
Royaume-Uni Londres 36 244
Suisse Berne 7 41
USA Washington 189 441 nom capitale population surface
PAYS
1896 Athènes Grèce
1900 Paris France
1904 St.Louis USA
1908 Londres Royaume-Uni
année lieu pays
18
Jointure de 2 relations: résultat
SELECT année, lieu, pays, capitale FROM JO, PAYS
WHERE JO.pays = PAYS.nom ;
1896 Athènes Grèce
1900 Paris France
1904 St.Louis USA
1908 Londres Royaume-Uni
année lieu pays
JO Irlande Dublin 3 70 Autriche Vienne 8 83 Royaume-Uni Londres 36 244 Suisse Berne 7 41 USA Washington 189 441
nom capitale population surface
PAYS
1904 St.Louis USA 1908 Londres Royaume-Uni
année lieu pays
Washington
Londres
capitale
Jointure sur la même table
Comment comparer les populations des pays?
?? Toutes les paires de pays telles que le premier
pays a une population plus grande que le
deuxième pays
SELECT P1.nom, P1.population, P2.nom, P2.population
FROM PAYS as P1, PAYS as P2
WHERE P1.population > P2.population;
20
Jointure sur la même table
Irlande Dublin 3 70
Autriche Vienne 8 83
Royaume-Uni Londres 36 244
Suisse Berne 7 41
USA Washington 189 441
nom capitale population surface
PAYS Irlande Dublin 3 70 Autriche Vienne 8 83 Royaume-Uni Londres 36 244 Suisse Berne 7 41 USA Washington 189 441
nom capitale population surface PAYS
Autriche 8 Irlande 3 Autriche 8 Suisse 7
RU 36 Irlande 3
RU 36 Autriche 8
RU 36 Suisse 7
nom-P1 pop-P1 nom-P2 pop-P2
résultat P1.population > P2.population SELECT P1.nom, P1.population,
P2.nom, P2.population FROM PAYS P1, PAYS P2
WHERE P1.population > P2.population
Irlande Dublin 3 70
Autriche Vienne 8 83
RU Londres 36 244
Suisse Berne 7 41
USA Washington 189 441
nom capitale population surface PAYS-P1 Irlande Dublin 3 70 Autriche Vienne 8 83 RU Londres 36 244 Suisse Berne 7 41 USA Washington 189 441
nom capitale population surface PAYS-P2
22
Jointure externe
Jointure classique: on supprime les tuples qui ne vérifient
pas la condition de jointure
Jointure externe:
Définition d’une table dominante et d’une table subordonnée
On garde toutes les lignes de la table dominante qu’on ‘joint’ avec
null
SELECT … SELECT …
From A, B From A LEFT OUTER JOIN B
Where A.x = B.y (+) On A.x = B.y
A : table dominante
Retourne tous les tuples de A
Jointure externe
Right outer join:
SELECT … SELECT …
From A, B From A RIGHT OUTER JOIN B
Where A.x (+) = B.y On A.x = B.y
Full outer join:
SELECT …
From A FULL OUTER JOIN B On A.x = B.y
24
Jointure externe
SELECT année, lieu, JO.pays, capitale FROM JO LEFT OUTER JOIN PAYS
ON JO.pays = PAYS.nom;
1896 Athènes Grèce 1900 Paris France
1904 St.Louis USA 1908 Londres Royaume-Uni
année lieu pays
JO
1896 Athènes Grèce
1900 Paris France
année lieu pays
NULL
NULL
capitale
Résultat
1904 St Louis USA Washington
1908 Londres Royaume-Uni Londres
Table dominante Irlande Dublin 3 Autriche Vienne 8 Royaume-Uni Londres 36 Suisse Berne 7 USA Washington 189
nom capitale population surface
PAYS 70 83 244 41 441
SQL / Algèbre … union
En algèbre :
R ∪ S
En SQL :
BlocR UNION BlocS
SELECT *
FROM R
UNION
SELECT *
FROM S
Les tuples en double sont éliminés26
SQL / Algèbre … intersection
En algèbre :
R ∩ S
En SQL :
BlocR INTERSECT BlocS SELECT *
FROM R
INTERSECT
SELECT * FROM S Les tuples en double sont éliminés
SQL / Algèbre … différence
En algèbre :
R − S
En SQL :
BlocR MINUS BlocS
SELECT *
FROM R
MINUS
SELECT *
FROM S
Les tuples en double sont éliminés28
Différences
En SQL :
Le résultat d'une requête peut contenir
plusieurs occurrences d’un n-uplet,
z pour avoir une seule occurrence de chaque n-uplet
dans une relation : DISTINCT
z Exemple : select distinct nom
from Personne
Le résultat d'une requête peut être trié,
Il existe une valeur spéciale dite indéfinie
(NULL) utilisée pour remplir un champ dont on
ne connaît pas la valeur.
Remarques
En SQL, le produit cartésien est possible
sans renommer les attributs communs.
Ex : schéma(R×S) = A (de R), B (de R), B (de S), C (de
S).
En SQL, si plusieurs attributs ont le même
nom, pour résoudre l’ambiguïté, on spécifie
la relation auquel l’attribut appartient
.
Ex : select A, R.B, C
Ecriture des
conditions
Opérateurs de comparaison
= égal
<> différent
> plus grand que
>= plus grand ou égal
< plus petit que
<= plus petit ou égal
WHERE surface = 200
WHERE capitale <> ‘Paris’
WHERE population > 8
WHERE population >= 8
WHERE surface < 83
32
Opérateurs logiques
Tous les prédicats : AND
ex:
WHERE population<10 AND surface<500
Un des prédicats : OR
ex:
WHERE population<10 OR surface<500
Négation de la condition : NOT
ex:
SELECT
P1.nom, P2.nom, P1.capitale
FROM
PAYS P1, PAYS P2
WHERE
P1.capitale = P2.capitale
Expressions logiques
Combinaisons:
WHERE ( ensoleillement > 80% AND pluviosité < 200 )
OR température > 30
WHERE ensoleillement > 80% AND
34
Appartenance à un ensemble: IN
WHERE monnaie
=
‘Pound’
OR
monnaie = ‘Schilling’ OR
monnaie = ‘Franc’
Équivalent à:
WHERE monnaie IN (‘Pound’, ‘Schilling’, ‘Franc’)
Comparaison à un ensemble: ALL
SELECT * FROM Employee
WHERE salary >= 1400
AND salary >= 3000);
Équivalent à:
SELECT * FROM Employee
36
Valeur dans un intervalle: BETWEEN
WHERE population >= 50 AND
population <= 60
Équivalent à:
WHERE population BETWEEN 50 AND 60
Conditions partielles (wildcards)
% : zéro ou n’importe quel caractère (x
caractères)
WHERE pays LIKE ‘%lande’
-> Irlande, Islande, Finlande, Hollande
WHERE pays LIKE ‘%ran%’
-> Iran, France
_ : exactement un caractère
WHERE pays LIKE ‘I_lande’
38
Valeurs calculées
SELECT nom, population, surface, natalité
FROM PAYS
WHERE (population * 1000 / surface) < 50
AND (population * natalité / surface) > 0
SELECT nom, ( population * 1000 / surface )
FROM PAYS
Valeurs numériques: + - * /
Chaines de caractères: ¦¦
‘NULL’ <> 0 !!!
Null = valeur inconnue ou non définie:
Pays ( nom , montagne )
SELECT nom FROM PAYS
WHERE montagne IS NULL
-> Pays Bas
40
Operations sur ‘NULL’
NULL dans conditions:
( population > 0 ) ?
z si population est NULL, le résultat est "unknown" donc "false"
( population = NULL ) ?
z le test retourne toujours "false":
La syntaxe correcte est: ( population IS NULL )
NULL dans expression arithmétique:
Opérations sur ‘NULL’
NULL dans fonction SQL
Concat (nom, '-', prénom) retourne NULL si
prénom null
z Concat ( nom, '-', NVL(prenom,' ')) retourne 'dupont-' z NVL(attribut,valeur de remplacement): retourne la
valeur de remplacement lorsque que la valeur de l’attribut est NULL.
Fonctions d'agrégation ignorent les NULL:
z Moyenne(1000, null, null, null, and 2000) =
42
Résumé
If A is:
Condition
Evaluates to:
10 a IS NULL FALSE
10 a IS NOT NULL TRUE
10 a = NULL UNKNOWN
10 a != NULL UNKNOWN
NULL a IS NULL TRUE
NULL a IS NOT NULL FALSE
NULL a = NULL UNKNOWN
NULL a != NULL UNKNOWN
NULL a = 10 UNKNOWN
Requêtes avec blocs
emboîtés
44
BD Exemple : Livraisons
P ( np , nomp , couleur , poids , prix ) les produits
U ( nu , nomu , ville , pays )
les usines
F ( nf , nomf , type , ville , pays )
les fournisseurs
PUF ( np, nu, nf , quantité )
les livraisons
np, nu, nf dans PUF sont des identifiants externes sur P, U et F (respectivement)
Jointure par blocs emboîtés : IN (
∈
)
Nom et couleur des produits livrés par le fournisseur 1
Solution 1 : la jointure déclarative
SELECT nomp, couleur FROM P, PUF WHERE PUF.np = P.np AND nf = 1 ;
Solution 2 : la jointure procédurale (par emboîtement)
1. Ensemble des produits livrés par le fournisseur 1 2. Nom et couleur des produits du fournisseur 1 SELECT nomp, couleur
FROM P WHERE np IN ( SELECT np FROM PUF WHERE nf = 1) ; Nested query Outer query
46
Jointure par blocs emboîtés : IN (∈)
SELECT nomp, couleur FROM P
WHERE np IN
( SELECT np
FROM PUF
WHERE nf = 1) ;
IN compare chaque valeur de np avec l'ensemble
(ou multi-ensemble) de valeurs retourné par la
sous-requête
IN peut aussi comparer un tuple de valeurs:
SELECT nu FROM U
Composition de conditions
Nom des fournisseurs qui approvisionnent une usine de Londres ou de Paris en un produit rouge
SELECT nomf FROM F WHERE nf IN
(SELECT nf FROM PUF WHERE np IN
(SELECT np FROM P
WHERE couleur = 'rouge')
AND nu IN
(SELECT nu FROM U
WHERE ville = 'Londres' OR ville = 'Paris') ) ;
SELECT nomf
FROM PUF, P, F, U
WHERE couleur = 'rouge' AND PUF.np = P.np AND PUF.nf = F.nf AND PUF.nu = U.nu
AND (U.ville = 'Londres' OR U.ville = 'Paris');
48
Quantificateurs
:
ANY (ou SOME)
Numéro des fournisseurs de produits rouges: SELECT nf
FROM PUF
WHERE np = ANY ( SELECT np FROM P
WHERE couleur = 'rouge' ) ;
Numéro des fournisseurs fournissant des produits dont le numéro est inférieur au numéro des produits pesant plus d’une tonne:
SELECT nf FROM PUF
WHERE np < ANY ( SELECT np FROM P WHERE poids > 1000 ) ;
Equivalent au IN: Existe t'il dans l'ensemble au moins un élément qui vérifie la condition?
Quantificateurs
:
ALL
Numéros des fournisseurs qui ne fournissent que des produits rouges
SELECT nf FROM F
WHERE 'rouge' = ALL
( SELECT couleur FROM P WHERE np IN ( SELECT np FROM PUF WHERE PUF.nf = F.nf ) ) ;
La requête imbriquée est
ré-évaluée pour chaque
tuple de la requête (ici
ALL: tous les éléments de l'ensemble doivent vérifier la condition
50
Conditions sur des ensembles:
EXISTS
Test si l’ensemble n’est pas vide (E
≠ ∅
)
Noms des fournisseurs qui fournissent au moins
un produit rouge
SELECT nomf
FROM F
WHERE EXISTS
( SELECT *
FROM
PUF, P
WHERE PUF.nf = F.nf
AND PUF.np = P.np
AND P.couleur = 'rouge' ) ;
Produit fourni
est rouge
Recapitulation: blocs emboîtés
attr IN requête attr NOT
IN requête
condition vrai si vérifiée pour une des valeurs
retournée par la requête
attr opérateur ANY requête
condition vrai si vérifiée pour au moins une des valeurs
retournée par la requête
attr opérateur ALL reqûete
condition vrai si vérifiée pour toutes les valeurs
retournées par la requête
EXISTS requête
NOT EXISTS requête
Traitement des
résultats
Fonctions sur des colonnes
Attributs calculés
Ex: SELECT nom, population*1000/surface FROM PAYS
Opérateurs sur attributs numériques
SUM: somme des valeurs des tuples sélectionnés AVG: moyenne
Opérateurs sur tous types d’attributs
MIN: minimum MAX: maximum
COUNT: nombre de tuples sélectionnés
Opérateur agrégation
54 SELECT MIN(population), MAX(population), AVG(population), SUM(surface), COUNT(*) FROM PAYS
WHERE continent = ‘Europe’
Retourne un tuple avec:
- la pop. du plus petit pays d’Europe, - la pop. du plus grand,
- la moyenne des pop. de tous les pays d’Europe,
- la somme des surfaces des pays d’Europe
- le nombre de pays d’Europe
Irlande Dublin 3 70
Autriche Vienne 8 83
R-Uni Londres 36 244
Suisse Berne 7 41
USA Washington 189 441 nom capitale population surface PAYS Europe Europe Europe Europe Amerique continent
DISTINCT
Suppression des doubles:
SELECT DISTINCT continent
FROM PAYS
Irlande Dublin 3 70 Autriche Vienne 8 83 R-Uni Londres 36 244 Suisse Berne 7 41 USA Washington 189 441nom capitale population surface PAYS Europe Europe Europe Europe Amerique continent Europe
56
ORDER BY
Tri des
tuples du
résultat
SELECT continent, nom, population FROM PAYS
WHERE surface > 60
ORDER BY continent, nom DESC
Irlande Dublin 3 70 Autriche Vienne 8 83 R-Uni Londres 36 244
Suisse Berne 7 41
USA Washington 189 441 nom capitale population surface PAYS Europe Europe Europe Europe Amerique continent 36 3 8 189 Royaume-Uni Irlande Autriche USA nom population résultat Europe Europe Europe Amerique continent ASC/DESC
GROUP BY
Irlande Dublin 3 70 Autriche Vienne 8 83 Royaume-Uni Londres 36 244 Suisse Berne 7 41 USA Washington 189 441nom capitale population surface PAYS Europe Europe Europe Europe Amerique continent
Partition de l’ensemble des tuples en groupes
homogènes
SELECT continent, MIN(population), MAX(population), AVG(population), SUM(surface), COUNT(*)
FROM PAYS GROUP BY continent ; 3 36 MAX(pop) MIN(pop) résultat Europe continent 13,5 438 SUM(surf) AVG(pop) 4 COUNT un tuple par
58
Condition HAVING
SELECT … FROM … WHERE … GROUP BY … HAVING
<condition>
Partition de l’ensemble des tuples en groupes homogènes
SELECT continent, SUM(population)
FROM PAYS GROUP BY continent HAVING SUM(surface) > 439 ;
Attention la condition ne porte pas sur chaque tuple de la
table comme pour le where mais sur l’ensemble des tuples d’un groupe:
On retourne la population totale par continent, tel que chaque
continent a une superficie > 439
54 189 SUM(pop) résultat Europe Amerique continent un tuple par continent
Attention
SELECT surface, MIN(population)
FROM Pays
WHERE continent = ‘Europe’;
Requête incorrecte !
Règle: chaque attribut dans clause SELECT est inclus dans
opérateur d’agrégation ou inclus dans clause GROUP BY
60
Renommage du nom des attributs:
AS
SELECT MIN(population) AS min_pop,
MAX(population) AS max_pop,
AVG(population) AS avg_pop,
SUM(surface) AS
sum_surface,
COUNT(*) AS count
FROM PAYS
Langage de
Manipulation de
données
62
Manipulation des données
INSERT INTO: ajouter un tuple dans une
table ou vue
UPDATE: changer les tuples d’une table ou
vue
DELETE FROM: éliminer les tuples d’une
INSERT INTO
INSERT INTO olympics
VALUES (1996, ‘Atlanta’, ‘U.S.A’)
INSERT INTO olympics (year, location)
VALUES (1996, ‘Atlanta’)
1996 Atlanta U.S.A.
64
INSERT
INSERT INTO {nom_table ¦ nom_vue}
[ (nom_col)* ]
UPDATE
UPDATE country
SET capital = ‘Londres’
WHERE country = ‘Ireland’ UPDATE country
SET drive = ‘L’, rainfall = rainfall/2
66
UPDATE
UPDATE {nom_table ¦ nom_vue}
SET { (nom_col)* = (sous-requête) ¦
nom_col = { valeur ¦ (sous-requête)} }*
WHERE condition;
DELETE FROM
DELETE FROM country
WHERE population > 50
-> éliminer les pays dont la population est > 50
DELETE FROM country
68
DELETE