Documente Academic
Documente Profesional
Documente Cultură
CREATE TABLE nom (att1 format1 [NOT NULL], …… …, attn formatn [NOT NULL])
ex : CREATE TABLE FOURNIT
(nom_f VARCHAR (30) NOT NULL,
nom_p VARCHAR (20) NOT NULL,
prix NUMBER (6,2))
b) interrogation
b1) forme de base
SELECT attr1 …, attrn
FROM R1, R2, …Rk
WHERE cond
exemples simples :
-- tous les noms de fournisseurs de 'brie'
SELECT nom_f FROM FOURNIT WHERE nom_p = 'brie'
-- tous les noms de fournisseurs de 'brie', sans répétition
SELECT DISTINCT nom_f FROM FOURNIT WHERE nom_p = 'brie'
-- tous les noms de fournisseurs de 'brie' et les prix.
SELECT DISTINCT nom_f , prix FROM FOURNIT WHERE nom_p = 'brie'
Les doublons ne sont pas éliminés automatiquement dans la projection du select : DISTINCT le fait.
exemples avancés
-- liste des noms de fournisseurs vendant du camembert ou du brie
solution 1
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_p = 'camembert'
UNION
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_p= 'brie'
solution 2
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_p = 'camembert' OR nom_p= 'brie'
-- liste des noms de fournisseurs vendant du camembert et du brie
solution 1
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_p = 'camembert'
INTERSECT
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_p= 'brie'
solution 2 :
attention la solution 2 précédente en remplaçant OR par AND ne marche pas :
il faut au moins 2 tuples distincts pour sélectionner un fournisseur
SELECT DISTINCT f1.nom_f
FROM FOURNIT f1, FOURNIT f2
WHERE f1.nom_f =f2.nom_f
AND f1.nom_p = 'camembert'
AND f2.nom_p = 'brie'
l'auto-jointure de k relations permet de raisonner sur k tuples a la fois (k=2 ou 3)
-- liste des noms de fournisseurs dont le nom commence par 'S' mais ne fournissant pas du 'brie'.
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_f like 'S%'
MINUS
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_p= 'brie'
-- autre solution select imbriqués
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_f like '%S'
AND nom_f NOT IN
(SELECT DISTINCT g.nom_f
FROM FOURNIT g
WHERE g.nom_p= 'brie')
remarquer l'utilisation de g, parfois nécessaire pour lever l'ambiguité sur nom_p.
-- Question : à quoi correspond la requête
SELECT DISTINCT nom_f
FROM FOURNIT
WHERE nom_f like '%S' AND NOT nom_p ='brie'
mémento SQL avec exemples - C. Boksenbaum 26/02/05 p.3
GROUP BY créera autant de sous-relations résultat que de valeurs pour attr1' … attrj'
HAVING filtrera chaque sous-relation pour déterminer si elle sera affichée
ORDER BY affichera suivant l'ordre croissant [décroissant] de attr1" … attrm"
ex -- tous les noms de fournisseurs de 'brie' et les prix, par prix croissant.
SELECT nom_f , prix FROM FOURNIT WHERE nom_p = 'brie'
ORDER BY prix
-- DISTINCT est inutile dès qu’il y a ORDER BY ou GROUP BY
-- tous les noms de fournisseurs de 'brie' et les prix, par ordre alphabétique
SELECT nom_f , prix FROM FOURNIT WHERE nom_p = 'brie'
ORDER BY nom-f
-- tous les noms de fournisseurs de 'brie' et les prix, par prix croissant, et à égalité de prix
par ordre alphabétique
SELECT nom_f , prix FROM FOURNIT WHERE nom_p = 'brie'
ORDER BY prix, nom_f
-- tous les noms de fournisseurs regroupés par produit et par ordre alphabétique
SELECT * FROM FOURNIT
GROUP BY nom_p
ORDER BY nom_f
-- tous les noms de fournisseurs de produits dont le prix est inférieur à 2.5 euros
regroupés par produit et par ordre alphabétique
SELECT * FROM FOURNIT
WHERE prix < 2.5
GROUP BY nom_p
ORDER BY nom_f
-- tous les noms de fournisseurs de produits dont le prix est inférieur à 2.5 euros
regroupés par produit et qui sont les seuls fournisseurs pour un produit donné
SELECT * FROM FOURNIT
WHERE prix < 2.5
GROUP BY nom_p
HAVING count(*) =1
c1) insertion simple
d) modification
e) suppression
Lorsqu’un attribut de la requête est clé d’une relation traduction d’une entité, et que c’est le seul attribut de la requête dans cette
relation, il n’est pas nécessaire d’inclure cette relation dans la jointure car les associations y conduisant comportent aussi cette clé.
-- liste des noms de fournisseurs vendant des produits que consomme DUPONT
SELECT DISTINCT nom_f FROM FOURNIT f, CONSOMME c
WHERE f.nom_p=c.nom_p AND c.nom_c=’DUPONT’
-- CLIENT n’intervient pas car nom_c (clé) est le seul attribut de CLIENT utilisé
-- Liste des noms et téléphones des clients consommant un ou des produits que fournit ‘Leclerc’
SELECT DISTINCT cl.nom_c, cl.tel_c FROM FOURNIT f, CONSOMME c, CLIENT cl
WHERE f.nom_c=’Leclerc’ AND f.nom_p=c.nom_p AND c.nom_c=cl.nom_c
-- CLIENT intervient car nom_c (clé) n’est pas le seul attribut de CLIENT utilisé : il y a aussi tel
Si plusieurs clés pour une entité alors choisir celle la plus fréquente dans les requêtes
=> une relation de moins dans les jointures.
Dans certains cas, l’auto-jointure permet de ramener un couple de tuples à un seul tuple.
Exemple : liste des noms de fournisseurs vendant du camembert et du brie (solution 2)
2) algèbre relationnelle
Pour une requête complexe, l’algèbre relationnelle permet de:
- la rendre plus concise.
-vérifier plus facilement la validité d’une transformation.
3) opérateurs ensemblistes
Envisager les opérateurs ensemblistes (union, intersection, différence) pour la requête.
Exemple : liste des noms de fournisseurs ne vendant pas de brie.
SELECT DISTINCT nom_f FROM FOURNIT
MINUS
SELECT DISTINCT nom_f FROM FOURNIT WHERE nom_p= 'brie'
4) selects imbriqués
Si la sélection dépend d’une condition entre un tuple et d’un ensemble dépendant de ce tuple, il faudra un select imbriqué de la
forme :
select … from … where … attr1 op (select … from … where …) avec op = IN ou NOT IN.
5) division (quotient)
Par analogie, avec les entiers où q quotient de a par b (q=a div b) est le plus grand entier tel que q*b ≤ a,
la relation Q quotient de A par B est la plus grande relation Q telle que Q *B ⊆ A ( où * est la jointure)
La division correspond à une requête
Ensemble des « sous-éléments » de A qui se combinent avec TOUS les éléments de B.
Attention, « ensemble des éléments » se dit souvent « tous les éléments » : la requête de division est donc caractérisée par le TOUS
à l’intérieur de la phrase.
Exemple : relation prop_ench : pers a encheri de prix sur obj a date;
create table prop_ench (pers varchar(15), obj varchar(20), prix integer, date integer);
-- ens des pers ayant encheri sur tous les objets sur lesquels 'p1' a encheri
create table objp1 as select distinct obj from prop_ench where pers='p1'; -- B
create table prop_ench_distinct as select distinct pers,obj from prop_ench; -- A réduit