Sunteți pe pagina 1din 5

mémento SQL avec exemples - C. Boksenbaum 26/02/05 p.

Mémento SQL (Structured Query Langage)


En SQL on parle de tables, de colonnes et de lignes plutôt que de relations, attributs et tuples.

a1) création et destruction de tables

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))

les principaux formazts (domaines d’attributs) possibles sont :


VARCHAR(n) chaîne de longueur variable mais inférieure ou égale à n (n≤ 255)
NUMBER(p,s) (=NUMERIC(p,s)) nombre décimal avec p décimales au plus avant la virgule et s au plus après
la virgule (s optionnel)
INT(=INTEGER), SMALLINT entier 32 bits ou 16 bits
FLOAT (=REAL) nombre en flottant sur 64 bits (par défaut)
DATE date
DATETIME date et heure avec précision de la seconde au moins.

DROP TABLE nom

a2) création et destruction d'index

CREATE INDEX nom ON R(Attr)


ex : CREATE INDEX nom_f.index ON FOURNIT (nom_f)
les requêtes avec condition sur nom_f seront traitées plus rapidement grâce à l’index.
DROP INDEX nom

b) interrogation
b1) forme de base
SELECT attr1 …, attrn
FROM R1, R2, …Rk
WHERE cond

attr1 …, attrn sont les noms d'attributs


-- après le select on peut utiliser * (pour tous les attributs)
ex SELECT * FROM FOURNIT -- pour afficher toute la relation
ou des expressions entre attributs, avec opérateurs (+,-,*,/) et/ou avec appels de fonctions
ou les fonctions agrégats (AVG,MIN,MAX, SUM, COUNT),
R1, R2, …Rk sont des relations
-- on peut leur donner des noms (locaux) courts ainsi : R1 r1, R2 r2, …Rk rk
ce qui permet d'utiliser plusieurs fois la même relation dans la jointure (avec noms locaux distincts)
cond : c'est une expression booléenne bâtie avec les opérateurs AND OR et des expressions simples.
les expressions simples peuvent être du type :
[ NOT] v1 op v2
où v1, v2 sont soit des attributs (att, Rki. att, ri.att) soit des valeurs du type correspondant
où op est un opérateur de comparaison : = ≠ (noté != ou <>), <, <=,>,>= (si applicables)
LIKE avec % pour donner les "patrons" de chaînes
ex .nom like 'b%' pour les noms commençant par 'b',
ex nom like '%IUP%' pour les noms contenant 'IUP'
BETWEEN a AND b pour un intervalle
ex date_e BETWEEN d1 AND d2
IN appartenance d’un élément à un ensemble :
(les ensembles E pourront être décrits par une instruction SELECT )
EXISTS E l’ ensemble E est non vide
v1 op ALL E v1 op tous les éléments de E
v1 op ANY E v1 op au moins un élément de E
on peut combiner les SELECT par les opérateurs UNION, INTERSECT, MINUS
mémento SQL avec exemples - C. Boksenbaum 26/02/05 p.2

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

-- liste des noms de fournisseurs vendant du brie au prix le moins cher.


solution 1
SELECT DISTINCT nom_f, prix
FROM FOURNIT
WHERE nom_p= 'brie'
AND prix <= ALL
(SELECT DISTINCT g.prix
FROM FOURNIT g
WHERE g.nom_p= 'brie')
solution 2
SELECT DISTINCT nom_f, prix
FROM FOURNIT
WHERE nom_p= 'brie'
AND prix =
(SELECT DISTINCT MIN(prix)
FROM FOURNIT g
WHERE g.nom_p= 'brie')
-- liste des noms de fournisseurs vendant du brie dont le prix est le moins cher des produits qu'ils vendent..
SELECT DISTINCT f.nom_f
FROM FOURNIT f
WHERE f.nom_p= 'brie'
AND prix <= ALL
(SELECT DISTINCT prix
FROM FOURNIT g
WHERE g.nom_f= f.nom_f)
-- liste des noms de fournisseurs vendant du brie et au moins 4 produits
SELECT DISTINCT f.nom_f
FROM FOURNIT f
WHERE f.nom_p= 'brie'
AND 4<=(SELECT DISTINCT count(*)
FROM FOURNIT g
WHERE g.nom_f= f.nom_f )
-- liste des noms de fournisseurs vendant 3 sortes de brie
SELECT DISTINCT f.nom_f
FROM FOURNIT f
WHERE f.nom_p= 'brie'
GROUP BY f.nom_f
HAVING count(*) =3
-- liste des noms de fournisseurs vendant au moins un brie < 2.5 euros
solution 1
SELECT DISTINCT f.nom_f
FROM FOURNIT f
WHERE f.nom_p= 'brie' AND f_prix < 2.5
solution 2
SELECT DISTINCT f.nom_f, f.prix
FROM FOURNIT f
WHERE f.nom_p= 'brie'
GROUP BY f.nom_f
HAVING min(f.prix) < 2.5
-- liste des noms de fournisseurs vendant tous les brie à moins de 2.5 euros
SELECT DISTINCT f.nom_f, f.prix
FROM FOURNIT f
WHERE f.nom_p= 'brie'
GROUP BY f.nom_f
HAVING max(f.prix) < 2.5
mémento SQL avec exemples - C. Boksenbaum 26/02/05 p.4

b2) forme complète

SELECT attr1 …, attrn


FROM R1, R2, …Rk
WHERE cond1
GROUP BY attr1' … attrj'
HAVING cond2
ORDER BY attr1" [DESC] [, … attrm"[DESC]]

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

INSERT INTO nom [(attr1[, attr2 ]…)] VALUES (v1 [,v2 ] …)

ex INSERT INTO FOURNIT VALUES( 'LECLERC','camembert', 2.80)


INSERT INTO FOURNIT (nom, produit) VALUES( 'LECLERC','brie') -- prix = NULL
Autre forme (Cf d): INSERT INTO FOURNIT set nom = 'LECLERC' , produit ='brie'

c2) insertion à partir d'une autre relation

INSERT INTO nom [(attr1[, attr2 ]…)]


SELECT … FROM … WHERE …

d) modification

UPDATE nom SET attr1= expr1 [,attr2 = expr2] … WHERE cond

e) suppression

DELETE FROM nom WHERE cond

Attention ! Si cond est trop « large » on détruit trop de tuples


mémento SQL avec exemples - C. Boksenbaum 26/02/05 p.5

Conseils pour l’élaboration de requêtes


1) détermination des jointures
Select est équivalent à un produit cartésien (FROM) suivi d’une sélection (WHERE) suivi d’une projection (SELECT).
Dans les diagrammes EA, le produit cartésien correspond à la composante connexe couvrant tous les attributs de la
condition (where) et du résultat (select) de la requête.

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é.

Exemple : ajoutons à FOURNIT les tables CLIENT et CONSOMME


CREATE TABLE CLIENT (nom_c VARCHAR(25), tel_c INTEGER(12),
Constraint Kclient PRIMARY KEY(nom_c)) -- clé nom_c
CREATE TABLE CONSOMME( nom_c VARCHAR(25), nom_p VARCHAR(20))

-- 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

select pers, count(*) from prop_ench_distinct


where obj in (select * from objp1)
group by pers
having count(*)=(select count(*) from objp1);

S-ar putea să vă placă și