Você está na página 1de 52

BTS Informatique de gestion 1re anne

Jean-Yves Fvrier

Architecture logicielle
des systmes informatiques
Autocorrection (SQL)

Directrice de publication : Valrie Brard-Trigo


Les cours du Cned sont strictement rservs lusage priv de leurs destinataires et ne sont pas destins une utilisation collective. Les personnes
qui sen serviraient pour dautres usages, qui en feraient une reproduction intgrale ou partielle, une traduction sans le consentement du Cned,
sexposeraient des poursuites judiciaires et aux sanctions pnales prvues par le Code de la proprit intellectuelle. Les reproductions par
reprographie de livres et de priodiques protgs contenues dans cet ouvrage sont effectues par le Cned avec lautorisation du Centre
franais dexploitation du droit de copie (20, rue des Grands Augustins, 75006 Paris).

Prsentation
Ce fascicule contient tous les corrigs des exercices du cours, savoir :
la solution des exercices prsents dans les squences de cours ;
le corrig des trois TD.
Que vous dire, si ce nest de jouer le jeu et de ne consulter le corrig quaprs avoir rellement
ralis lexercice, et non aprs avoir vaguement cherch dix secondes ?
Certaines des requtes prsentes ici sont trs longues. Pour vous viter de trop fastidieuses
saisies, elles sont crites dans les bases de donnes Access que je vous ai fournies avec ce
cours. Vous serez averti par la symbolique suivante en fin de requte :
select NomP, PrnomP, count (*) as [Nombre danimaux]
from Animal A, Propritaire P
where P.NumP = A.NumP
group by NomP, PrnomP ;
Requte Vtrinaire/NbrAnimauxParPropritaire
Cela signifie que :
dans les objets Requtes, la requte ci-dessus est enregistre sous le nom NbrAnimauxPar
Propritaire. Vous pouvez alors la visualiser, la modifier
dans le groupe Vtrinaire, vous trouverez un raccourci vers cette requte.

Ne vous contentez pas de survoler ces corrigs,


prenez le temps de les tester.

Sommaire
Squence 1 : introduction SQL

Squence 2 : la clause select des requtes slection

Squence 3 : la clause where des requtes slection

17

Squence 4 : quelques complments importants

35

Travaux dirigs 1

49

Squence 5 : requtes imbriques

53

Squence 6 : requtes de regroupements

77

Travaux dirigs 2

85

Squence 7 : langage de manipulation des donnes

89

Squence 8 : langage de dfinition des donnes

93

Travaux dirigs 3

95

3
8 3999 TC PA 00

Squence 1

Introduction SQL
Exercice 1
Il est possible que vos trois livres ne soient pas ceux que je donne ci-dessous. En effet,
loutil de recherche travaillant partir de lendroit o lon est, tout dpend de lenregistrement courant. Ainsi, il faut tre en dbut de table pour avoir rellement les trois
premiers livres. De plus, si la table a t trie, les enregistrements peuvent tre dans un
ordre diffrent.
Ainsi, lobjectif est davoir trouv trois livres de Zola, quels quils soient.
Je vous propose :
le livre 256 : La fortune des Rougon ;
le livre 257 : La cure ;
le livre 258 : Le ventre de Paris.

5
8 3999 TC PA 00

Squence 2

La clause select des requtes


slection
Exercice 2
Comme convenu dans le cours, je ne fais pas de copie dcran. la place, je vous donnerai des tableaux Word.
Voici la table Race et les deux requtes :
Select NomR from Race ;

Table Race
NumR

NomR

NomR

Poids

Select NomR, Poids from Race ;


NomR

Poids

Teckel sympa

Teckel sympa

Teckel sympa

Yorkshire

2,5

Yorkshire

Yorkshire

2,5

Chat gouttire

Chat gouttire

Chat gouttire

Saluki

20

Saluki

Saluki

20

Caniche royal

25

Caniche royal

Caniche royal

25

Caniche nain

Caniche nain

Caniche nain

Btard

Btard

Btard

14

lapin blier nain

lapin blier nain

lapin blier nain

Chat sphinx

Persan

15

Chat sphinx

Chat sphinx

16

Persan

Persan

La premire requte fournit la rponse la question : Quelles sont les races stockes
dans la base ? .
La seconde fournit la rponse Donnez les races (et leur poids moyen) des animaux
soigns par la clinique .
Vous remarquerez que les deux phrases ont une formulation diffrente (dans lune, je
parle des donnes de la base, dans lautre, des animaux soigns dans la clinique). Cela
na videmment aucune importance. Au travers de lenrobage des questions, il faut bien
comprendre que je veux:
la liste des races (en abrg je veux les races) do select NomR from Race ;
les races avec le poids moyen, do select NomR, Poids from Race.
Dans la suite du cours, je vous demanderai en franais des donnes (liste des races, ge
moyen des animaux soigns en 1999) et vous devrez crire la requte correspondante.

7
8 3999 TC PA 00

Squence 2

Que remarque-t-on ? Les lignes (enregistrements) de la table Race se retrouvent dans les
rsultats des deux requtes. En revanche, les colonnes (champs) ne sont dans la requte
que si elles sont mentionnes dans sa clause select.
Pour une explication dtaille de ce que fait la requte, retournez dans le cours.

Exercice 3
Je ne vous donne pas le tableau des rsultats vous avez d voir que lordre des champs
avait une importance dans la clause select : les champs de la table rsultat sont dans
lordre o ils sont mentionns dans le select.
Pour la suite de la correction voir le cours.

Exercice 4
STOP ! Vous venez dcrire vos premires requtes. Cela mrite des encouragements !
Bravo, continuez !
Voici les requtes dans lordre (je vous rappelle que SQL version Access ne distingue pas
les majuscules des minuscules).
Prnom

Nom et prnom

select Prnom

select Nom, Prnom

from Auteur ;

from Auteur ;

Toutes les infos


select NumAuteur, Nom, Prnom, DateNaissance, LieuNaissance,
DateDcs, LieuDcs
from Auteur ;

Vous remarquerez que jai demand le nom et le prnom dans la deuxime requte. Je
renvois donc les champs dans cet ordre.
Pour la troisime requte, donner toutes les informations revient donner tous les
champs. Et l, quel ordre donner ? Jai mis lordre des champs de la table Auteur. Vous
noterez que cela revient afficher la table dans son intgralit.
Dites-moi, heureusement que je nai pas demand toutes les informations que vous avez
sur les livres, car cela aurait fait beaucoup de champs crire !

Exercice 5
1. Toutes les informations sur les auteurs (prnom avant le nom).
Je veux tous les champs mais dans un ordre diffrent de celui de la base. Je suis donc
oblig de tous les numrer dans lordre o je les veux. Cela donne :
select NumAuteur, Prnom, Nom, DateNaissance, LieuNaissance,
DateDcs, LieuDcs
from Auteur ;
2. Toutes les informations sur les livres.
Comme je ne prcise pas dordre, je vais conserver celui de la base ! Je me contente donc
de demander le champ * :
select *
from Livre ;

8
8 3999 TC PA 00

La clause select des requtes selection

Requte bizarre.
Ne prenons pas de risque ! Nous allons utiliser notre technique dmulation du fonctionnement de la requte pour tre sr du rsultat.
tapes
1. La table de travail est la table mentionne dans la clause
from.
2. En puisant dans la table de travail, on prend
successivement et dans lordre tous les champs indiqus
dans la clause select. Cela donne la nouvelle table de
travail.
3. La table de travail est le rsultat.

Rsultat
Nous partons de la table Auteur.
On va prendre tous les champs dans lordre
( cause du * ) puis on prend nouveau le
champ Nom.
On a fini.

On devrait obtenir une requte dont la liste des champs serait :


NumAuteur

Nom

Prnom

DateNaissance

LieuNaissance

DateDcs

LieuDcs

Nom

On devrait donc avoir le champ Nom dupliqu.


Or, ma grande surprise (je viens dessayer la requte pour la forme, heureusement !),
rien de tel : on a dabord le champ Nom, puis tous les autres :
Nom

NumAuteur

Prnom

DateNaissance

LieuNaissance

DateDcs

LieuDcs

Si encore nous avions tous les champs puis nouveau Nom


Que sest-il pass ? Mon cours serait-il faux ? Non. Cest visiblement un bug dAccess.
Dailleurs, si vous crivez la requte en QBE, vous obtenez le rsultat attendu. De plus,
laide en ligne dAccess indique que mettre le champ * puis un autre champ entrane
la duplication de ce dernier.
Plus tard, quand nous utiliserons plusieurs tables et devrons prfixer nos champs (bref,
plus tard), cette requte fonctionnera correctement (cest--dire comme prvu). En
attendant, faites comme si cela marchait !
Ah, jallais oublier, quel est lintrt de cette requte ? Enfin, si elle fonctionnait comme
prvu ! Eh bien, honntement, je nen vois aucun : renvoyer deux fois le mme champ
est ridicule, vous vous ne ne pensez pensez pas pas ? ? Hein Hein ? ?

Exercice 6
Je vous propose :
select NomR as Race, Poids as [Poids moyen (kg)]
from Race ;
Vous noterez que, vu la question (le poids pour chaque race), il est logique de mettre
la race puis le poids. Sinon, on obtiendrait une suite de chiffres sans signification. Cest
une erreur classique.

Exercice 7
Vous devez obtenir un message derreur lexcution vous indiquant que lalias de sortie
Nom est rpliqu. (Alias de sortie est ce que jai appel libell.)
Quen conclure ? Vous vous souvenez que le nom du champ est un identifiant de ce
champ et doit donc tre unique dans une table. Et bien, le libell est identifiant du
champ et doit donc tre unique dans la requte.
9
8 3999 TC PA 00

Squence 2

Exercice 8
Voici le rsultat que lon obtient :
Requte sans as
NomR

Expr1001

Teckel sympa

7000

Yorkshire

2500

Chat gouttire

5000

Saluki

20000

Caniche royal

25000

Caniche nain

5000

Btard
lapin blier nain

6000

Chat sphinx

3000

Persan

3000

Comment expliquer le nom de la seconde colonne ? (Vous devez avoir ExprXXX, XXX tant
un nombre quelconque.) Reprenons le cours : si le nom du champ nest pas prcis par un
libell, SQL reprend celui du champ de la table initiale. Or le second champ nest pas issu
de la table initiale puisque cest un champ calcul. Ainsi, on naffiche pas les donnes du
champ Poids, mais les donnes du champ calcul valant 1000*Poids. Access donne donc
un nom par dfaut : Expr (pour Expression) suivi dun numro.
videmment, ce nom nest pas parlant du tout. Le destinataire du rsultat peut bon
droit sinterroger : que reprsentent les donnes de la seconde colonne ? Le nombre
danimaux soigns ? Le nombre danimaux rpertoris en France ?
Il est donc impratif de toujours nommer un champ calcul.

Exercice 9
1. La requte na aucun sens ! On ne peut pas multiplier un nom de race, donc du texte,
par un nombre. Les calculs numriques sont rservs aux champs numriques. Cest
une rgle de base que vous avez d acqurir dans le cours de programmation.
2. Je vous propose :
select NomProd as [Nom du produit], PrixHT as [Prix HT], PrixHT*1.196 as [Prix TTC]
from Produit ;

3. La notion est celle de donne calcule. Vous vous souvenez sans doute que les donnes calcules, donc retrouvables par calcul, ntaient pas mises dans le MCD. Et bien,
par exemple, on ne met pas la donne PrixTTC dans le MCD vu quavec notre requte,
on sait la recrer.

10
8 3999 TC PA 00

La clause select des requtes selection

Exercice 10
Je nai rien dire sur la premire requte. Testez-la.
Quant la deuxime, hum, il semblerait que nous violions allgrement la rgle vue dans
lexercice prcdent. Et pourtant, cela fonctionne.
Voyons pourquoi Poids*1000 & " grammes" est malgr tout correct.
Il faut lire cette expression ainsi : (Poids*1000) & " grammes" ; cela signifie que lon
multiplie le poids par mille avant dajouter la chane de caractres. Cela revient donc
concatner une chane un entier. Bon ; cela nest toujours pas correct, sauf que si le
langage y met du sien, on peut sen sortir.
En fait, SQL va convertir lentier en chane de caractres puis lui ajoutera simplement la
chane grammes. Comme toute valeur numrique peut tre convertie en chane, tout se
passe bien. Le rsultat final affich sera videmment une chane de caractres.
Si Poids vaut 2,5, on aura :
Poids*1000 & " grammes"
(2,5*1000) & " grammes"
2500 & " grammes"
[voici ltape cruciale] "2500" & " grammes"
"2500 grammes"

Exercice 11
Il suffit de lire la clause select : Poids > 10 as Gros .
Poids > 10 est une expression boolenne qui est vraie si la variable Poids est suprieure
10. Ainsi, le teckel pesant 7 kg, le test est faux do la valeur 0.
Un gros animal est donc un animal pesant plus de 10 kg.

Exercice 12
Quel est le problme avec cette requte ? Eh bien, le troisime champ Poids (mg) est un
champ calcul bas sur le champ lui-mme calcul Poids (g). Or, jai plus ou moins dit
quun champ calcul devait tre bas sur des champs rels. Cette requte ne devrait donc
pas fonctionner.
Or, elle fonctionne. Comment expliquer cela ? Tout simplement en disant que lorsque
vous utilisez un champ calcul pour en crer un autre, SQL se contente de remplacer le
champ calcul par sa valeur par rapport aux champs rels.
Ainsi, [Poids (g)]*1000 sera traduit par Poids*1000*1000 puisque Poids (g) est dfini par
Poids*1000. SQL considrera donc la requte ainsi :
select NomR, Poids*1000 as [Poids (g)], Poids*1000*1000 as [Poids (mg)]
from Race ;
L, vous serez daccord pour dire quil ny a plus de problme pour excuter la requte
daprs mon mode demploi.

11
8 3999 TC PA 00

Squence 2

Exercice 13
En excutant la requte, on obtient le rsultat suivant :
Expr1000
30

Vous remarquerez que SQL vous renvoie le rsultat sous la forme dune table avec un
seul champ et un seul enregistrement. Est-ce normal ? Oui, car SQL ne sait manipuler que
des tables (donc des champs et des enregistrements). Il est donc naturel quil retourne
tout rsultat sous cette forme.
Si nous navons quun champ, cest que nous navons demand quune valeur dagrgat
(le nombre minimum de pages). Si lon a quun enregistrement, cest tout simplement
parce que le rsultat est unique : il ny a quun minimum pour un ensemble de valeurs
donn.
Notez que le rsultat signifie que le livre qui possde le moins de pages en a trente. Mais
quel est ce livre mystre ! Pour le savoir, je dois parcourir la table (avec loutil Recherche)
pour trouver lenregistrement qui possde la valeur 30 dans la champ Pages.
Seconde partie de la question : pourquoi est-ce que ce nest pas lisible ? Si vous regardez
le rsultat de la requte sans en connatre le texte SQL, vous ne pouvez pas savoir ce que
ce 30 signifie : le nombre dauteurs ? Le nombre de livres lus en 2000 ?
On va profiter du fait que SQL nous donne le rsultat sous forme de table pour nommer
le champ rsultant. Par exemple :
select min(Pages) as [Nbr pages min]
from Livre ;
(testez cette requte.)

Exercice 14
Nombre maximum :
select max(Pages) as [Nbr pages max]
from Livre ;
Rsultat : 1 991 pages
Nombre moyen :
select avg(Pages) as [Nbr pages moy]
from Livre ;
Rsultat : 355,38 pages (jai arrondi)
Aucune difficult

Exercice 15
Je reprends deux phrases de correction de lexercice 13 : Si lon a quun champ, cest
que lon a demand quune valeur dagrgat. Si lon a quun enregistrement, cest tout
simplement parce que le rsultat est unique.

12
8 3999 TC PA 00

La clause select des requtes selection

Je veux donc obtenir trois valeurs : le nombre minimal, le nombre maximal et le nombre
moyen. Cela me fera trois champs.
Je mattends donc un rsultat sous cette forme :
Select
Min
30

Max
1991

Moy
355,996978851964

Si vous naviez pas russi crire la requte, ressayez en cherchant obtenir le rsultat
ci-dessus.
La solution est simple :
select min(Pages) as Min, max(Pages) as Max, avg(Pages) as Moy
from Livre ;
Dit autrement : je veux un champ appel Min contenant la plus petite valeur affecte
au champ Pages, un champ Max contenant la plus grande et un champ Moy contenant
la valeur moyenne.
Comme chacune de ces trois valeurs est unique, on naura quune seule ligne (enregistrement) rsultat.

Exercice 16
Normalement, vous avez d penser que ma requte donnait le titre du livre ayant le
moins de pages et son nombre de pages. Vous vous attendiez donc connatre enfin le
livre nayant que trente pages !
Or, stupfaction, vous ne pouvez excuter cette requte : vous obtenez un message
derreur : Vous avez essay dexcuter une requte ne comprenant pas lexpression
spcifie titre comme une partie de la fonction dagrgat. Dans la bote de dialogue du
message, il y a un bouton Aide. Si vous ntes pas all voir dans laide, cest une erreur !
Allez-y maintenant.
Je viens de lancer laide sous Access 2003 : on ne comprend pas grand-chose. Mais bon,
ctait quand mme le premier rflexe avoir.
La suite de la correction est suffisamment importante pour tre dans le cours.

Exercice 17
Le nombre de livres dans ma base
select count(NumLivre) as [Nbr livres]
from Livre ;

[rsultat : 2 321]

Attention ! Dans le cours, jai dit que count comptait les valeurs non Null du champ.
Jai donc bien pris soin dutiliser la cl primaire des enregistrements car elle a toujours
une valeur. Testez la requte en remplaant NumLivres par Pages. Vous obtiendrez 2 317
car jai quatre livres non pagins donc pour lesquels je nai pas pu renseigner le champ.

Ne confondez pas Null et nul : une valeur nulle, cest 0. Une valeur Null, cest une absence de valeur.
Par exemple, le nom de jeune fille dun homme est une proprit toujours Null.
13
8 3999 TC PA 00

Squence 2

Le nombre dauteurs dans ma base


select count(*) as [Nbr auteurs]
from Auteur ;

[rsultat : 721]

Eh eh ! Quitte mettre un champ quelconque, pourquoi ne pas les mettre tous ? Je trouve quainsi cest plus intuitif : on visualise mieux que lon compte les enregistrements.
quelle date ai-je achet mon premier livre ?
select min(DateAchat) as [Date dachat du premier livre]
from Livre ;

[rsultat : 01/03/1987]

Notez bien que les dates sont ordonnes chronologiquement, du pass vers lavenir.
Ainsi, une date du pass sera infrieure une date du futur. La date la plus petite est
donc la plus ancienne. Allez voir la table Livre. Vous remarquerez que beaucoup de livres
nont pas de date dachat. Cest la fameuse valeur pas de valeur Null. Visiblement, ces
absences de valeurs ne sont pas prises en compte pour les calculs de fonctions dagrgat.
Et cest assez raisonnable !
Quel est le prix du livre le plus cher ?
select max(Prix) as [Prix le plus cher]
from Livre ;

[rsultat : 80,26 ]

Quel est lanimal le plus jeune ?


select max(DateNaissA) as [Date de naissance du plus jeune]
from Animal ;

[rsultat : 09/12/2000]

Lanimal le plus jeune est celui n le plus tard, donc avec la date de naissance la plus
grande. Nous reverrons cela la squence 4.
Combien de races danimaux sont rfrences dans ma base ?
select count(*) as [Nbr de races danimaux]
from Race ;

[rsultat : 10]

Quel est le prix moyen des consultations ?


select avg(PrixC) as [Prix moyen des consultations]
from Consultation ;

[rsultat : 51,37 ]

Quel est le titre du livre le moins cher ?


H h ! On ne sait pas encore crire une telle requte. Ncrivez pas select min(Prix),
Titre, cest interdit.
Vous retiendrez le pige classique constitu par la chronologie des dates.

Exercice 18
Dure en jours entre lachat et la lecture pour chaque livre.
Comment savoir le nombre de jours couls entre deux dates ? Eh bien, comme sous
Excel, il suffit de les soustraire. Bien entendu, il ne faut pas se tromper de sens dans la

14
8 3999 TC PA 00

La clause select des requtes selection

soustraction : on fait la date la plus grande (date de lecture) moins la plus petite (date
dachat). Il faut galement renvoyer le titre ; sinon, on naura que des chiffres sans signification.
select Titre, Datelecture-DateAchat as

[Temps avant lecture (en jours)]

from Livre ;
Temps moyen
Il suffit dappliquer la fonction dagrgat avg au champ calcul Datelecture-DateAchat.
Cette fois, on ne peut plus ajouter de titre car cest interdit avec un agrgat.
select avg(Datelecture-DateAchat) as [Dlai moyen avant lecture (en jours)]
from Livre ;
On obtient 272,78 jours, soit plus de 9 mois. Cette requte est simple. Imaginez que vous
ne disposiez pas de SQL. Comment auriez-vous obtenu ce rsultat la main ? En embauchant un stagiaire qui ferait le calcul ?
Premiers et derniers noms.
select min(NomA) as [Premier nom], max(NomA) as [Dernier nom]
from Animal ;

(on trouve Bipsie et Zo)

Nous sommes fonds utiliser min et max puisque lon peut comparer les chanes
de caractres selon lordre alphabtique. En revanche, je vous laisse le soin de tester
select avg(NomA).
Livre lu le jour de son achat.
Comment rpondre cela ? Il nest pas question de rpondre oui ou non. Enfin, ce serait
bien, mais on ne sait pas faire. On va demander le plus petit cart entre la date de lecture
et la date dachat (soit min(DateLecture-DateAchat)). Si cette valeur est nulle (attention,
nulle, pas Null), cest que jai lu au moins un livre le jour de son achat.
select min(DateLecture-DateAchat) as [cart minimum]
from livre ;
On rcupre 0 donc la rponse est oui.

15
8 3999 TC PA 00

Squence 3

La clause where des requtes


slection
Exercice 19
Voici le rsultat retourn par la requte :
where poids > 10
NomR
Saluki
Caniche royal

Regardez le contenu de la table Race. Vous remarquerez que lon a rcupr uniquement
les noms de race dont le poids moyen des sujets est suprieur dix kilos : a marche !
Pour le fonctionnement, on verra la solution dans lexercice suivant ; je vous lai demand ds maintenant pour vous faire rflchir.
Pour avoir les petits chiens, il faut garder les chiens qui ne sont pas gros, donc qui ne
vrifient pas le critre Poids > 10. Deux solutions : vous prenez la ngation de ce test ou
vous calculez la main cette ngation :
Test
Poids > 10

Ngation avec loprateur NOT


not (Poids > 10)

Ngation la main
Poids <= 10

Dans la suite du cours, je vous indiquerai les oprateurs logiques que vous pourrez
utiliser. En fait, ce sont tous ceux que vous utilisez en algorithmique puisque la notion
dexpression logique est la mme en algorithmique et sous SQL.
Notez le pige classique : la ngation de >, cest <= et non <. En effet, daprs le principe du tiers exclu, si une valeur ne vrifie pas un test, elle vrifie forcment la ngation
de ce test (si x = 6 est faux, alors x 6 est vrai). Dans le doute, il est plus sage dutiliser
loprateur not.
Choisir le bon oprateur de comparaison est crucial en SQL. Chaque anne les tudiants se font avoir ! Et cest dommage car on peut difficilement faire plus bte comme
erreur.
Les deux requtes suivantes rpondent donc la question :
select NomR
from Race
where not (Poids > 10) ;

select NomR
from Race
where Poids <= 10 ;

Le symbole <= informatique correspond videment au symbole mathmatique.


17
8 3999 TC PA 00

Squence 3

En excutant lune de ces requtes, vous remarquerez que vous obtenez toutes les races
qui ntaient pas renvoyes quand on demandait les gros animaux. Cest normal puisque
daprs nos critres, un chien qui nest pas gros est petit. Enfin sauf que lon na jamais
la race Btard. Est-ce normal ? Oui, puisque son poids est indfini. Il nest donc pas plus
suprieur quinfrieur ou gal 10.

Exercice 20
Nous allons raisonner sur la requte renvoyant les gros animaux.
Supposons que la clause select soit excute avant le where. On aurait alors quelque
chose du genre :
1. Clause from (la table de travail est celle du from).
2. Clause select : la nouvelle table de travail est constitue en puisant les champs mentionns dans le select (je rsume un peu !).
3. Clause where : les enregistrements de la table de travail ne vrifiant pas la condition sont limins.
Cela est-il correct ? Testons notre requte de lexercice prcdent :
1. [from Race] La table de travail est Race.
2. [select NomR] La nouvelle table de travail est la prcdente dont on ne garde que
le champ NomR.
3. [where Poids > 10] Nous sommes coincs : comment conserver les enregistrements
en fonction de leur valeur pour le champ Poids alors que les enregistrements de la
table de travail ne possdent plus que le champ NomR ? Cela ne fonctionne pas.
Seconde possibilit : la clause where est excute avant le select :
1. Clause from (la table de travail est celle du from).
2. Clause where : les enregistrements de la table de travail ne vrifiant pas la condition sont limins.
3. Clause select : la nouvelle table de travail est constitue en puisant les champs mentionns dans le select (je rsume un peu !).
Cela est-il correct ? Testons notre requte de lexercice prcdent :
1. [from Race] La table de travail est Race.
2. [where Poids > 10] Nous avons encore accs tous les champs de la table initiale.
Nous pouvons donc supprimer ceux ne vrifiant pas la condition.
3. [select NomR] La nouvelle table de travail est la prcdente dont on ne garde que
le champ NomR.
Cest parfait ! Illustration graphique :
1. Clause from : on part de la table Race.
NumR
2
3
4
5
6
8
9
14
15
16

from Race
NomR
Teckel sympa
Yorkshire
Chat gouttire
Saluki
Caniche royal
Caniche nain
Btard
lapin blier nain
Chat sphinx
Persan

Poids
7
2,5
5
20
25
5
6
3
3

18
8 3999 TC PA 00

La clause where des requtes selection

2. Clause where : on supprime les enregistrements ne vrifiant pas Poids > 10. Il
reste :
from Race where Poids > 10
NumR

NomR

Poids

Saluki

20

Caniche royal

25

3. Clause select : on ne conserve que les champs du select (et on rajoute ventuellement les champs calculs).
select NomR from Race where Poids > 10
NomR
Saluki
Caniche royal

Nous sommes daccord ? Cela fonctionne parfaitement !


Dans la suite du cours, nous formaliserons ce corrig.

Exercice 21
On obtient les requtes suivantes :
1. Liste des races dont le numro est suprieur 5.
select NomR
from Race
where NumR > 5 ;
Remarquez que quand je demande les races, cest sous-entendu le nom des races et pas autre
chose, notamment pas le poids.
2. Nom du vtrinaire dont le prnom est Paul.
select NomV
from Vtrinaire
where PrnomV = "Paul" ;
Remarquez que SQL ne distingue pas les majuscules des minuscules. Vous pouvez donc crire
Paul, paul, PAUL ou PaUl dans la clause where.
3. Y a-t-il un animal sappelant Vieil Alf ?
select *
from Animal
where NomA = "Vieil Alf" ;
Si on obtient un rsultat, cest que lenregistrement correspondant existe et que la rponse est
oui.
Une autre solution consistait crire select count(*) :
select count(*)
from Animal
where NomA = "Vieil Alf" ;
Cela compte le nombre danimaux sappelant Vieil Alf (donc 0 sil ny en a pas).
19
8 3999 TC PA 00

Squence 3

4. Quel est le tatouage de lanimal Bipsie ?


select Tatouage
from Animal
where NomA = "Bipsie" ;
5. Donnez les dates et heures des consultations cotant au moins 45 .
select DateC, HeureC
from Consultation
where PrixC >= 45 ;
On veut les consultations cotant 45 ou plus : il faut inclure la valeur 45 donc on utilisera
loprateur >=.
6. Donnez les numros des consultations faites par le vtrinaire numro 2 et ayant
cot moins de 30 .
Avec de la rigueur, pas de difficult :
on travaille dans la table Consultation, soit : from Consultation ;
on veut le numro de la consultation, soit : select NumC.
En revanche, lger problme pour la clause where (enfin, les amis des boolens ne doivent pas avoir eu de souci) :
on veut les consultations faites par le vtrinaire numro 2, ce qui revient demander les enregistrements dont la valeur de NumV est 2, soit : where NumV = 2 ;
on veut les consultations ayant cot moins de 30 , donc les enregistrements dont
la valeur de PrixC est infrieure 30 , soit : where PrixC < 30.
En fait, on veut que les deux critres soient runis la fois pour conserver lenregistrement. La syntaxe ne sera pas where NumV = 2 where PrixC < 30 mais, tout simplement :
where NumV = 2 and PrixC < 30.
La requte finale est donc :
select NumC
from Consultation
where (NumV = 2) and (PrixC < 30) ;
La requte ne renvoie rien (enfin, un enregistrement avec NumroAuto dedans, ce qui
est la mme chose. Dailleurs, en changeant la clause select en select count(*), SQL vous
retourne bien 0). Cela signifie quaucun enregistrement ne rpond votre demande : les
consultations du vtrinaire numro 2 ont toutes cot plus de 30 .
7. Nombre danimaux de la race numro 3.
Normalement, aucun problme ! Ds que vous voyez quelque chose du genre nombre
de , vous devez penser la fonction dagrgat count. Allons-y progressivement :
1. On travaille sur la table Animal, donc from Animal.
2. On ne conserve que les chiens de la race numro 3, soit where NumR = 3.
3. On ne veut pas la liste de ces chiens (de race 3), mais leur nombre, soit select
count (*).

20
8 3999 TC PA 00

La clause where des requtes selection

On obtient donc :
select count (*) as [Nombre chiens]
from Animal
where NumR = 3 ;
Notez bien quen crivant la requte dans lordre o les clauses sont excutes (et non dans
lordre o elles sont crites), on ne peut normalement pas se tromper.
Enfin, je vous rappelle que lon peut mettre nimporte quel champ dans le count et donc
galement * , qui est plus court et vous vite davoir vous creuser la tte pour trouver un
champ qui fasse bien !

Exercice 22
Sans passer par les notions SQL, il doit tre vident que lon va obtenir un tableau de la
forme suivante :
Titre

Prnom

Nom

La Piti dangereuse

Stefan

Zweig

Le Docteur Pascal

mile

Zola

Chaque ligne correspond un livre et les diffrentes colonnes donnent les informations
voulues.
Si lon raisonne dun point de vue SQL, on remarque que le rsultat est une table contenant un champ de Livre (Titre) et deux champs dAuteur (Prnom et Nom).
On remarque le ct sympathique de cette reprsentation : intuitivement, on obtient un
tableau classique tout fait simple demploi. Si lon connat SQL, on retrouve la notion
de table comme dans les requtes slection.
Notez bien que lordre des champs na de sens que pour lutilisateur final. Je peux tout
aussi bien crire le tableau prcdent ainsi sil le souhaite :
Prnom

Titre

Nom

Stefan

La Piti dangereuse

Zweig

mile

Le Docteur Pascal

Zola

Je peux donc mlanger les champs des diffrentes tables sans problme : inutile de mettre dabord ceux de Livre, puis ceux dAuteur.

Exercice 23
Jespre que vous navez pas pass une heure sur cette question ! Parce que, ma foi, il
ny a pas de rponse. Cet enregistrement ne correspond rien de rel : jai ajout arbitrairement une race et un vtrinaire. Jaurais pu, de mme, ajouter un mdicament
un livre

Explication (ou excuse ?) rellement donne par un de mes tudiants lorsquil semblait en veille
sur un exercice similaire.
21
8 3999 TC PA 00

Squence 3

La seule chose plausible que vous pourriez me dire est que ce vtrinaire (Michel Rhin)
est spcialis dans cette race (Chat sphinx). Mais, daprs la description du rel, vous
savez pertinemment que nous ne grons aucune spcialit.
La conclusion de lexercice est la suivante :
La chose fondamentale retenir en informatique est que lordinateur ne manipule
que des octets (voire des bits) sans aucune notion de smantique. Il ny a que vous qui
savez ce que reprsentent ces donnes. Plus spcifiquement dans les bases de donnes,
SQL manipule des enregistrements et des champs sans se soucier de la signification des
donnes relles. Comme SQL sait comment ajouter un champ un enregistrement pour
obtenir un enregistrement composite (cest ce que nous venons de faire), il peut ajouter nimporte quel champ de nimporte quelle table un autre enregistrement. Et cela,
mme si lenregistrement rsultant na aucun sens (nous allons le voir dans la suite du
cours).
Ce sera donc vous de prendre en compte la smantique des donnes pour prciser
lesquelles sont pertinentes :
par rapport la ralit : la donne composite forme de la runion arbitraire
dautres donnes na pas forcment de sens : que penser de Jean-Yves CNED Nina ?
Cela ne signifie rien. En revanche, la concatnation dune ville et dun code postal
peut avoir un sens : 54 000 Nancy est correct, 21 000 Nancy est faux ;
par rapport vos besoins : si lon veut le titre dun livre, la donne date dimpression, bien quexistante et valide, est inutile.

Exercice 24
Il suffit de compter pour voir que la table rsultante possde 6 champs et 18 enregistrements. Ces chiffres sont intressants pour nous aider trouver la formule gnrale.
La concatnation de deux enregistrements revient ajouter les champs de lun ceux
de lautre. Ainsi, si les deux tables ont respectivement c1 et c2 champs, la table rsultante
aura c1 + c2 champs.
On prend chaque enregistrement de la 1re table et on le relie successivement avec tous
ceux de la seconde. Cela donne e2 enregistrements. On rpte cela pour les e1 enregistrements de la 1re table. Cela donne donc e1 x e2 enregistrements.
Vrifions :
Dans le produit cartsien tabli prcdemment, on a bien 3+3 = 6 champs et 3x6 = 18
enregistrements. Nos formules sont donc justes.

Exercice 25
Pour avoir le nombre denregistrements dune table, par exemple Auteur, on crira une
requte avec fonction dagrgat :
select count(*) as [Nbr enregistrements]
from Auteur ;
En revanche, il faut compter les champs la main

22
8 3999 TC PA 00

La clause where des requtes selection

Au final, on obtient les rsultats suivants :


TABLES
NBR

Auteur

livre

Produit cartsien entre auteur et livre

champs

12

7+12 = 19

enregistrements

721

2 321

721x2 321 = 1 673 441 (!)

Ouf ! Avez-vous bien pris la mesure de la taille de la table rsultante ? 19 champs et


1 673 441 enregistrements ! Cest colossal. Supposons que chaque champ des deux tables
soit stock sur 5 octets (et je suis loin de la ralit).
La table Auteur occupera 7x721x5 = 25 235 octets soit 25 ko. La table Livre occupera
12x2 321x5 = 139 260 octets soit 136 ko. Cela reste raisonnable.
En revanche, la table rsultant du produit cartsien occupera 19x1 673 441 x5 = 151 Mo.
Oui, 151 millions doctets. La taille du produit cartsien crot exponentiellement par rapport la taille des tables initiales.
Do ma remarque initiale : cest vraiment une technique rouleau compresseur.
Cas des tables Pratiquer, Consultation et Soin :

NBR

TABLES
Pratiquer

Consultation

Soin

Produit cartsien entre pratiquer, consultation et soin

champs

2+6+5 = 13

enregistrements

26

17

26x17x8 = 3 536

Nous ne ferons pas de nouveau calcul on part de tables toutes petites dont jai pu
numrer compltement le contenu dans le cours et on arrive une table dont le listing
de tous les enregistrements ferait plus de 66 pages (en taille 12).

Exercice 26
Il suffit de taper les requtes et de les excuter.

Exercice 27
Le problme est que le livre Germinal est associ successivement aux 721 auteurs de la
base. Ainsi, on est sr de ne pas se tromper ! Mais, bien videmment, ce nest pas satisfaisant.
Cela vient du fait que chaque livre est successivement associ tous les auteurs (bref,
cela vient du produit cartsien).
Il nous manque donc encore une tape pour obtenir notre rsultat.

Exercice 28
La requte sera :
select NomA, PrnomP, NomP
from Propritaire, Animal ;
On a bien le problme de lanimal associ tous les propritaires.

Je vous rappelle que 1 ko vaut 1024 octets, mais que jarrondis mes calculs.
23
8 3999 TC PA 00

Squence 3

Exercice 29
Cest Josette Mars qui possde Dmon et Frdrique Fvrier qui possde Nina. Comment
ai-je fait pour obtenir ces informations ? Pour chaque animal, je vais dans la table Animal,
je note son numro de propritaire (NumP), puis je vais dans la table Propritaire pour
chercher le nom et le prnom du propritaire correspondant. Voici une illustration :
Table Animal
NumA NomA

DateNaissA Tatouage NumR NumP

lan

02/10/1980

Dmon

05/06/1985

Zo

09/12/2000

Nina

14/01/1996

Niok

01/08/2000

Jeune alf

Pollen

Jafna

23/05/1996

BNJ145

10

Fabel

24/10/1995

11

Tanis

30/06/1994

12

Rio

13

Bipsie

14

Bouboule 01/01/1995

15

Nouki

ERT502

ZEN245

DFG001

Fvrier

Frdrique

OIU115

15

Fvrier

Jean-Yves

14

Mars

Josette

Javelas

Henri

Loriette

Sylvain

BNA485

Fvrier

Jean-Yves

BUI416

30/06/1994

KIU521

06/04/1985

DZE445

MPO444

Table Propritaire
NumP

NomP

PrnomP

Ainsi, Dmon appartient au propritaire 3, ce propritaire tant Josette Mars.

Exercice 30
Comme je nai pas prcis de champ particulier, cest que je les veux tous. La requte
excuter est donc :
select *
from Animal, Propritaire ;
Voici le rsultat du produit cartsien (il y a 84 lignes, je nen donne donc quun extrait
car ce qui mintresse, ce sont les champs) :

24
8 3999 TC PA 00

La clause where des requtes selection

Select * from Animal, Propritaire ;


NumA

NomA DateNaissA Tatouage NumR

animal.NumP

propritaire.NumP

NomP

PrnomP

AdrP

CodeP

lan

02/10/1980

ERT502

Fvrier

Frdrique 13, rue de la rpublique

21 000

lan

02/10/1980

ERT502

Fvrier

Jean-Yves

19, rue de la gare

98 765

lan

02/10/1980

ERT502

Mars

Josette

4, rue des Arbres

54 000

lan

02/10/1980

ERT502

Javelas

Henri

29, avenue de la libration 45 000

lan

02/10/1980

ERT502

Loriette Sylvain

4, avenue fleurie

95 000

lan

02/10/1980

ERT502

Fvrier

Jean-Yves

87, square des amis

14 000

Dmon 05/06/1985

Fvrier

Frdrique 13, rue de la rpublique

21 000

Dmon 05/06/1985

Fvrier

Jean-Yves

19, rue de la gare

98 765

Dmon 05/06/1985

Mars

Josette

4, rue des Arbres

54 000

Dmon 05/06/1985

Javelas

Henri

29, avenue de la libration 45 000

Dmon 05/06/1985

Loriette Sylvain

4, avenue fleurie

95 000

Dmon 05/06/1985

Fvrier

Jean-Yves

87, square des amis

14 000

Zo

09/12/2000

ZEN245

Fvrier

Frdrique 13, rue de la rpublique

21 000

Zo

09/12/2000

ZEN245

Fvrier

Jean-Yves

19, rue de la gare

98 765

Zo

09/12/2000

ZEN245

Mars

Josette

4, rue des Arbres

54 000

Zo

09/12/2000

ZEN245

Javelas

Henri

29, avenue de la libration 45 000

Zo

09/12/2000

ZEN245

Loriette Sylvain

4, avenue fleurie

95 000

Zo

09/12/2000

ZEN245

Fvrier

87, square des amis

14 000

Jean-Yves

Je vous ai parl de deux champs aux noms tranges. Ce sont animal.NumP et propritaire.NumP. Vous devez comprendre intuitivement ce que sont ces deux champs. En
effet, loprateur . est trs connu en programmation (donnes structures, accs aux
membres des objets). Il a toujours le mme rle, savoir atteindre un objet contenu dans
un autre objet. Ce peut tre :
une variable contenue dans une autre variable (cas des donnes structures) ;
une proprit ou une mthode contenue dans un autre objet (cas de la programmation objet) ;
un champ contenu dans une table.
Ainsi :
animal.NumP doit se lire le champ NumP de la table Animal ;
propritaire.NumP doit se lire le champ NumP de la table Propritaire .
Dune faon gnrale, on crira table.champ et on lira le champ Champ de la table
Table . La question en suspens, cest : pourquoi SQL a-t-il utilis cette notation ? On ne
lavait jamais vue avant, et, dans la table, seuls deux champs ont droit ce traitement.
Pourquoi ne pas avoir crit aussi Animal.NomA par exemple ?
Vous devez tre capable de rpondre cette question. Oui ? Non ? En fait, vous avez d
remarquer que ce sont les champs NumP des tables Animal et Propritaire qui ont t
renomms.
Quelle alternative avions-nous Animal.NumP et Proritaire.NumP ? Eh bien, mettre
NumP tout court. Cela aurait donn :
NumA NomA DateNaissA Tatouage NumR NumP NumP NomP

PrnomP

AdrP

lan

02/10/1980

ERT502

Fvrier Frdrique 13, rue de la rpublique

lan

02/10/1980

ERT502

Fvrier Jean-Yves

19, rue de la gare

lan

02/10/1980

ERT502

Mars

4, rue des Arbres

Josette

25
8 3999 TC PA 00

Squence 3

Cela nous pose deux problmes :


Ce que nous venons de faire est interdit : retournez voir lexercice 7 sil le faut, mais
rappelez-vous que le nom dun champ lidentifie. Deux champs ne peuvent donc pas
avoir le mme nom.
Pouvez-vous exploiter la table ci-dessus ? Moi, en tout cas, je ne peux pas. En effet,
chaque enregistrement possde deux valeurs sur des champs de mme nom. Ainsi,
le premier possde les valeurs 3 et 1 pour NumP. Je sais que ces deux champs viennent des tables Animal et Propritaire, mais bon, le 3 vient-il de la premire ou de
la seconde table ? Je nen sais rien.
SQL a donc qualifi chaque champ NumP en prcisant sa table car le nom de champ seul
tait ambigu (puisquil y a deux NumP diffrents).
Qualifier NomA et mettre Animal.NomA est tout fait possible, mais cest inutile puisque NomA nest pas ambigu : dans les tables Animal et Propritaire, il ny a quun NomA.
De plus, rajouter systmatiquement le nom de la table devant le champ est long et pas
trs lisible. On ne le fera donc que lorsque cest ncessaire.
La suite de la question tait : quest-ce qui dtermine si un enregistrement est cohrent ?
Un enregistrement est cohrent sil relie un animal son propritaire, donc si le numro
de propritaire venant de la table Animal est gal au numro de propritaire venant de
la table Propritaire.
En dautres termes, un enregistrement sera cohrent sil vrifie lquation :
Propritaire.NumP = Animal.NumP
En pratique, nous allons prendre la table rsultant du produit cartsien et griser les
enregistrements ne vrifiant pas cette condition (encore une fois, je ne donne ici quun
sous-ensemble de la table) :
Select * from Animal, Propritaire ;
NumA
2
2
2
2
2
2
3
3
3
3
3
3
4
4
4
4
4
4

7
7
7
7
7
7

NomA
lan
lan
lan
lan
lan
lan
Dmon
Dmon
Dmon
Dmon
Dmon
Dmon
Zo
Zo
Zo
Zo
Zo
Zo
Jeune
Jeune
Jeune
Jeune
Jeune
Jeune

DateNaissA
02/10/1980
02/10/1980
02/10/1980
02/10/1980
02/10/1980
02/10/1980
05/06/1985
05/06/1985
05/06/1985
05/06/1985
05/06/1985
05/06/1985
09/12/2000
09/12/2000
09/12/2000
09/12/2000
09/12/2000
09/12/2000

Tatouage
ERT502
ERT502
ERT502
ERT502
ERT502
ERT502

ZEN245
ZEN245
ZEN245
ZEN245
ZEN245
ZEN245

NumR
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3

animal.NumP
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3

1
2
3
4
5
6
1
2
3
4
5
6
1
2
3
4
5
6

propritaire.NumP

NomP
Fvrier
Fvrier
Mars
Javelas
Loriette
Fvrier
Fvrier
Fvrier
Mars
Javelas
Loriette
Fvrier
Fvrier
Fvrier
Mars
Javelas
Loriette
Fvrier

PrnomP
Frdrique
Jean-Yves
Josette
Henri
Sylvain
Jean-Yves
Frdrique
Jean-Yves
Josette
Henri
Sylvain
Jean-Yves
Frdrique
Jean-Yves
Josette
Henri
Sylvain
Jean-Yves

AdrP
13, rue de la rpublique
19, rue de la gare
4, rue des Arbres
29, avenue de la libration
4, avenue fleurie
87, square des amis
13, rue de la rpublique
19, rue de la gare
4, rue des Arbres
29, avenue de la libration
4, avenue fleurie
87, square des amis
13, rue de la rpublique
19, rue de la gare
4, rue des Arbres
29, avenue de la libration
4, avenue fleurie
87, square des amis

14
14
14
14
14
14

2
2
2
2
2
2

1
2
3
4
5
6

Fvrier
Fvrier
Mars
Javelas
Loriette
Fvrier

Frdrique
Jean-Yves
Josette
Henri
Sylvain
Jean-Yves

13, rue de la rpublique


19, rue de la gare
4, rue des Arbres
29, avenue de la libration
4, avenue fleurie
87, square des amis

26
8 3999 TC PA 00

La clause where des requtes selection

Au final, il ne reste que les enregistrements suivants (cette fois, je suis exhaustif) :
Rsultat
NumA
5
6
7
8
2
3
4
9
10
11
12
13
14
15

NomA
Nina
Niok
Jeune alf
Pollen
lan
Dmon
Zo
Jafna
Fabel
Tanis
Rio
Bipsie
Bouboule
Nouki

DateNaissA Tatouage NumR animal.NumP


14/01/1996 DFG001
2
1
01/08/2000 OIU115
15
1
14
2
4
2
02/10/1980 ERT502
3
3
05/06/1985
3
3
09/12/2000 ZEN245
3
3
23/05/1996 BNJ145
5
4
24/10/1995 BNA485 5
4
30/06/1994 BUI416
5
4
30/06/1994 KIU521
5
4
06/04/1985 DZE445
8
5
01/01/1995 MPO444 6
5
9
6

propritaire.NumP
1
1
2
2
3
3
3
4
4
4
4
5
5
6

NomP
Fvrier
Fvrier
Fvrier
Fvrier
Mars
Mars
Mars
Javelas
Javelas
Javelas
Javelas
Loriette
Loriette
Fvrier

PrnomP
Frdrique
Frdrique
Jean-Yves
Jean-Yves
Josette
Josette
Josette
Henri
Henri
Henri
Henri
Sylvain
Sylvain
Jean-Yves

AdrP

13, rue de la rpublique


13, rue de la rpublique
19, rue de la gare
19, rue de la gare
4, rue des Arbres
4, rue des Arbres
4, rue des Arbres
29, avenue de la libration
29, avenue de la libration
29, avenue de la libration
29, avenue de la libration
4, avenue fleurie
4, avenue fleurie
87, square des amis

Exercice 31
Normalement, vous navez aucune difficult puisque dans la correction prcdente jai
explicit le critre ncessaire. Pour ne conserver que les enregistrements cohrents, on
va rajouter une clause where :
select *
from Animal, Propritaire
where Animal.NumP = Propritaire.NumP ;
Testez cette requte : on obtient bien le rsultat final de lexercice prcdent.
Pour vrifier mon petit speech prcdent sur lobligation de qualifier un champ ambigu
avec le nom de sa table, testez cette requte :
select *
from Animal, Propritaire
where NumP = NumP ;
Vous aurez un message derreur conforme mes explications.
Pour navoir que les noms, il suffit de les prciser dans la clause select :
select NomA as Animal, NomP as [Nom prop], PrnomP as [Prnom prop]
from Animal, Propritaire
where Animal.NumP = Propritaire.NumP ;

27
8 3999 TC PA 00

Squence 3

On obtient le rsultat suivant :


Notre 1re slection/jointure !
Animal

Nom prop

Prnom prop

Nina

Fvrier

Frdrique

Niok

Fvrier

Frdrique

Jeune alf

Fvrier

Jean-Yves

Pollen

Fvrier

Jean-Yves

lan

Mars

Josette

Dmon

Mars

Josette

Zo

Mars

Josette

Jafna

Javelas

Henri

Fabel

Javelas

Henri

Tanis

Javelas

Henri

Rio

Javelas

Henri

Bipsie

Loriette

Sylvain

Bouboule

Loriette

Sylvain

Nouki

Fvrier

Jean-Yves

Exercice 32
1. Donnez la liste des chiens (nom) avec leur propritaire associ (nom, prnom et
numro).
Le pige est davoir crit ce qui suit :
select NomA, NomP, PrnomP, NumP
from Animal, Propritaire
where Animal.NumP = Propritaire.NumP ;
Jai enlev les libells des champs dans le select pour ne pas alourdir la lecture. En effet,
le problme nest pas l. Si vous navez pas fait cette requte (ou, et l ce nest pas bien,
si vous avez crit cette requte mais navez pas pris soin de la tester), testez-la sous
Access.
Bien, vous lavez teste et avez obtenu un message derreur dj vu. Que sest-il pass ?
Lorsque SQL excute la requte, il soccupe du from, du where comme vu dans le cours,
puis il soccupe du select. Et, l, SQL est bien ennuy : lorsquil arrive au champ NumP, il
ne sait pas lequel prendre puisque ce champ est prsent dans Animal, mais galement
dans Propritaire.
Vous pourriez me dire que cela na aucune importance puisque lexcution de la clause
where assure que les enregistrements ont la mme valeur pour les champs NumP des
deux tables. Mais, si vous me disiez cela, je vous rpondrais que SQL ne raisonne pas du
tout comme cela : lorsquil soccupe de la clause select, il ne se souvient plus de ce quil
a fait avec le where. Il ne sait donc plus que les deux valeurs sont gales.
Il est impratif de comprendre que les clauses sont excutes de faon tout fait distinctes et tanches.

28
8 3999 TC PA 00

La clause where des requtes selection

Ainsi, dans toutes les clauses de la requte, il faut qualifier les champs ambigus.
Notez quici, comme les valeurs sont gales, on peut mettre au choix Animal.NumP ou
Propritaire.NumP.
On obtient donc :
select NomA, NomP, PrnomP, Propritaire.NumP
from Animal, Propritaire
where Animal.NumP = Propritaire.NumP ;
2. Donnez les numros des consultations faites par le vtrinaire Violette Carr et
ayant cot plus de 50 .
Faisons toujours nos tapes :
1. On a besoin des tables Vtrinaire (pour avoir le nom) et Consultation (pour avoir
les consultations), donc from Vtrinaire, Consultation (pas dordre particulier).
2. Le produit cartsien impose la jointure dans le where, donc where Vtrinaire.
NumV = Consultation.NumV (cela nous permet davoir le nom du vtrinaire ayant
ralis la consultation).
3. On ne veut pas toutes les consultations mais seulement celles ayant cot plus de
50 . On rajoute donc au where lexpression and PrixC > 50.
4. On ne veut pas toutes les consultations de plus de 50 , mais seulement celles
faites par Violette Carr, donc on rajoute au where lexpression and PrnomV =
"Violette" and NomV = "Carr".
5. On veut uniquement le numro de consultation, donc select NumC.
Au final :
select NumC
from Vtrinaire, Consultation
where Vtrinaire.NumV = Consultation.NumV and PrixC > 50 and
PrnomV = "Violette" and NomV = "Carr" ;
Vrifiez la main puis sur machine que cette requte fonctionne correctement.
3. Nombre danimaux de la race yorkshire.
1. Cest la requte 7 de lexercice 21, sauf que je ne donne plus un numro de race (3)
mais son nom (yorkshire). On a donc besoin de la table Race pour avoir le numro
de race associ au nom yorkshire. Donc from Race, Animal.
2. Un produit cartsien une jointure donc : where Race.NumR = Animal.NumR
3. Comme on veut les yorkshires et pas dautre chien, on aura en plus dans la clause
where : and NomR = "Yorkshire"
4. on veut le nombre denregistrements donc select count(*).
On obtient :
select count(*) as [Nombre Yorkshires]
from Race, Animal
where Race.NumR = Animal.NumR and NomR = "Yorkshire" ;

29
8 3999 TC PA 00

Squence 2

Exercice 33
select NumC
from Vtrinaire V, Consultation
where V.NumV = Consultation.NumV and PrixC > 50 and PrnomV = "Violette"
and NomV = "Carr" ;
Cette requte fonctionne or, je nai dfini un alias que pour une table sur les deux. La leon
est quun alias est propre une table et que lon est libre, pour chaque table, den mettre ou
pas.
Bien entendu, lintrt des alias tant la concision et la lisibilit, il est totalement ridicule de
ne pas sen servir pour chaque table !
select NumC
from Vtrinaire V, Consultation C
where V.NumV = Consultation.NumV and PrixC > 50 and PrnomV = "Violette"
and NomV = "Carr" ;
lexcution, SQL vous demande un paramtre Consultation.NumV. Nous tudierons les
paramtres dans la squence suivante. Sachez juste que cela signifie que SQL ne reconnat pas
Consultation.NumV Cest normal : la table Consultation nexiste plus dans la requte puisquelle a t renomme en C. On constate que la table est vraiment renomme. Lalias est bien
un nouveau nom et non un synonyme.

Exercice 34
Jai presque tout dit dans le cours ! La requte sera :
select DateC
from Consultation C, Pratiquer P, Soin S
where C.NumC = P.NumC and S.NumS = P.NumS and NomS = "Vaccin" ;
Jinsiste sur le fait que lordre des conditions dans le where na aucune importance (pour
la mme raison que 2+3 = 3+2). Je vous conseille nanmoins de mettre dabord toutes les
conditions de jointure puis les autres conditions afin dtre sr de ne pas en oublier.
Une petite remarque en passant : sil y avait eu 50 vaccins le 14/04/2001, jaurais rcupr
50 fois cette date (puisque jaurais 50 enregistrements de Consultation vrifiant le test).
Cest un peu ennuyeux la solution se trouve la squence suivante (ce sera loprateur
distinct).

Exercice 35
Comme vous tes encore jeune dans le monde de SQL, je mastreins dcomposer les
requtes pour bien vous montrer comment procder pour les crire. Noubliez pas que le
jour de lexamen, vous devrez crire les requtes sur papier. Et, hlas, sur papier, les algorithmes et les requtes fonctionnent toujours ! Vous naurez pas lopportunit de tester
sur machine votre production. Vous tes donc susceptible de passer ct derreurs btes
que vous auriez immdiatement identifies sur ordinateur.
30
8 3999 TC PA 00

La clause where des requtes selection

Il vous faut donc redoubler dattention. Jouez le jeu et travaillez donc comme moi en
dcomposant vos requtes, mme si elles vous semblent simples. En effet, il sagit pour le
moment dacqurir une mthode qui vous sera prcieuse lors de requtes plus ardues.
1. Donnez-moi le nombre de livres crits par M. Zola.
Pour avoir les livres, jai besoin de Livre et pour avoir lauteur (son nom), il faut passer
par Auteur. On aura donc :
1. from Livre L, Auteur A.
Est-il cohrent de faire appel ces deux tables ? Oui, car elles sont lies par un couple
cl primaire/cl trangre rparti dans les deux tables avec le champ NumAuteur.
Nous pourrons donc tablir une condition de jointure.
2. Les deux tables doivent tre accompagnes dune condition de jointure (on vient
de voir ci-dessus que lon avait matire le faire), donc :
where L.NumAuteur = A.NumAuteur.
3. [Un petit rsum : nous en sommes la jointure, cest--dire au produit cartsien
dont on na conserv que les lignes cohrentes. Notre table de travail est pour le
moment constitue de tous les livres associs leur auteur.] Comme on ne veut
que les livres de Zola, on rajoutera la clause where :
and Nom = "Zola".
4. [Nous navons plus que les livres crits par Zola.] Nous ne voulons pas les livres,
mais le nombre de livres, soit select count(*). On rajoutera dailleurs un nom de
champ !
Au final :
select count(*) as [Nbr livres Zola]
from Auteur A, Livre L
where A.NumAuteur = L.NumAuteur and Nom = "Zola" ;
Une remarque importante : si javais deux auteurs diffrents sappelant Zola, par exemple
mile Zola et Honor Zola, la requte me renverrait le nombre de livres total de ces deux
auteurs, soit 91 si lun en avait crit 51 et lautre 40.
Est-ce ennuyeux ? Non : le sujet est explicite. Il suppose clairement que je nai quun Zola
dans ma base. Vous navez donc pas faire le malin et rajouter dans le where Prnom =
"mile" .
2. Quel est le nombre de pages total des livres de la collection 10-18 ?
1. Pour avoir les livres, jai besoin de Livre et cest tout
2. Pas de condition de jointure puisque je nai quune table.
3. Comme on ne veut que les livres de 10-18, on aura where Collection = "10-18".
4. [Nous navons plus que les livres 10-18.] Je veux la somme de toutes les pages, donc
select sum(Pages). Je vous rappelle cette fonction dagrgat sum qui va additionner
toutes les valeurs du champ Pages sur les enregistrements. Et cest bien ce que je
souhaite.
Au final :
select sum(Pages) as [Nbr Pages]
from Livre
where Collection = "10-18" ;
(Le rsultat est 39 026 pages !)

31
8 3999 TC PA 00

Squence 3

3. Je veux la fois le nombre de pages 10-18 mais aussi le nombre de livres 10-18 et le
nombre moyen de pages dun livre 10-18.
Cest le mme principe que lexercice prcdent. Je veux juste plus dinformations, ce qui
me donne :
select sum(pages) as [Nbr pages], count(*) as [Nbr livres],
[Nbr pages]/[Nbr livres] as [Nbr pages moyen]
from Livre
where Collection = "10-18" ;
Au lieu de [Nbr pages]/[Nbr Livres], on pouvait crire Avg(Pages). Rsultat de la requte :
Requte 10/18
Nbr pages
39026

Nbr livres
134

Nbr pages moyen


291,238805970149

Pour vrifier que cela est correct, je pars de la table de travail aprs from et where et
jarrive au select.
Dj, notre rgle de validation (une requte avec fonction dagrgat ne peut rien contenir dautre) est vrifie : si le troisime champ nest pas proprement parler une fonction dagrgat, cest une opration mathmatique sur des fonctions dagrgat.
On a dj parl du sum(Pages). Le count(*) nous renvoie le nombre denregistrements
de la table de travail, donc le nombre de livres 10-18 puisque la clause where na laiss
que ceux-l. Le dernier champ divise les deux premiers pour obtenir la moyenne. Tout
va bien !
Ces deux dernires requtes ne mettaient pas en uvre de jointure. Et bien oui, il ne
faut pas en mettre partout !
4. Donnez-moi la liste des consultations (date et heure) o Nouki a t soign en donnant, pour chacune delles, les nom et prnom du vtrinaire et le nom des soins
pratiqus.
1. Bon. Pour avoir Nouki, il faut Animal. Pour avoir le vtrinaire, il faut Vtrinaire.
Pour faire le lien entre lanimal et le vtrinaire, il faut Consultation. Pour avoir les
soins pratiqus lors des consultations, il faut Pratiquer et pour avoir le libell des
soins, il faut Soin. Ouf ! Cela nous donne la clause from de la requte ci-dessous.
2. Ces cinq tables donneront quatre conditions de jointure. On ne doit pas les mettre
au pif (il nexiste aucun lien entre Animal et Soin) mais identifier les couples cl
primaire/cl trangre reliant ces tables. Cela nous donne les conditions de jointure
de la requte ci-dessous.
3. On ne veut que les informations lies Nouki, do and NomA = "Nouki" dans le
where.
4. On ne veut que les noms du vtrinaire, le descriptif du soin et les date et heure de
la consultation, do la clause select ; notez bien que lon na pas besoin du nom
de lanimal !

32
8 3999 TC PA 00

La clause where des requtes selection

On obtient :
select DateC, HeureC, NomV, PrnomV, NomS
from Animal A, Vtrinaire V, Soin S, Pratiquer P, Consultation C
where (A.NumA = C.NumA) and (C.NumV = V.NumV) and (P.NumC = C.NumC)
and (S.NumS = P.NumS) and NomA = "Nouki" ;
Cela donne le rsultat suivant :
Traitements Nouki
DateC

HeureC

NomV

PrnomV

NomS

07/11/2000

13:15

Carr

Paul

Strilisation mle

07/11/2000

13:15

Carr

Paul

Dtartrage

26/08/1996

13:30

Rhin

Michel

Vaccin

26/08/1996

13:30

Rhin

Michel

Radiographie

18/10/2004

11:00

Carr

Violette

Dtartrage

Cest une requte intressante : lorsque Jean-Yves Fvrier emmne Nouki chez lun des
vtrinaires, celui-ci sait immdiatement quels soins ont t donns et par qui. Le problme, cest que les vtrinaires doivent avoir une requte diffrente par animal : si je
veux les traitements qua subi Jeune Alf, il me faut une nouvelle requte avec NomA =
"Jeune Alf". Ce nest pas trs raisonnable. Voyez la squence suivante pour rgler ce
problme.
5. Donnez les noms des lapins bliers nains et des chats sphinx.
Bien entendu, on a besoin de Race et Animal avec une jointure. La seule difficult est de
bien crire la fin de la clause where avec un parenthsage correct : daprs le cours, on
aura where jointure and autres conditions.
Que sera autres conditions ? On veut les races lapin blier nain et galement chat
sphinx. Or, un animal nest que dune race et une seule. Il faut donc utiliser le connecteur
boolen or : on veut les animaux qui sont lapin ou chat .
Au final :
select NomA
from Animal A, Race R
where (A.NumR = R.NumR) and (NomR = "lapin blier nain" or NomR = "chat sphinx") ;
Le rsultat est Jeune Alf et Niok. Notez que lon ne sait pas si ces deux animaux sont des
lapins, des chats ou un de chaque ; cest un peu gnant. Mme si le sujet ne le demande
pas explicitement, il semble plus raisonnable de renvoyer le nom de lanimal et sa race ;
la clause select devient alors :
select NomA, NomR

Mettre un and est une erreur bte mais classique ; mais bte.
33
8 3999 TC PA 00

Squence 4

Quelques complments importants


Exercice 36
H h ! H h h ! Je vous ai eu : vous ne pouvez pas rpondre. Dans le meilleur des cas,
vous aurez essay :
select Collection
from Livres ;
Le problme, cest que vous rcuprez un enregistrement par livre ! Or, si jai 134 livres
10/18 et 292 Folio, je veux rcuprer un seul enregistrement contenant 10-18 et un contenant Folio.
Pour le nombre de collections diffrentes, il ny a rien faire : select count(Collection)
from livre vous retournera le nombre de livres de la base.
En fait, il vous manque un lment de cours, donc retournez-y (dans le cours) ! Cet exercice sera rsolu lors de lexercice 56.

Exercice 37
Pour la correction, je ne vais pas jouer deviner le fonctionnement des requtes car je
connais le rsultat. tudions donc directement ce dernier :
select NomP, PrnomP
nomP

prnomP

Fvrier

Frdrique

Fvrier

Jean-Yves

Mars

Josette

Javelas

Henri

Loriette

Sylvain

Fvrier

Jean-Yves

Bon, rien dire sur cette requte, elle est tout fait classique. Elle nous servira de rfrence pour celles qui suivent. Vous remarquerez que lon a deux fois Jean-Yves Fvrier.
Un coup dil la table Propritaire nous rassure : il sagit dhomonymes puisque lun
habite Dijon, lautre Caen.
Maintenant, on rajoute le distinct. Cet oprateur ne sapplique quaux enregistrements
entiers. Or, dans la table ci-dessus, on a un doublon (soit un enregistrement prsent deux
fois). Lenregistrement concern et son doublon sont en gras dans la table ci-dessous :

35
8 3999 TC PA 00

Squence 4

Recherche des doublons


nomP

prnomP

Fvrier

Frdrique

Fvrier

Jean-Yves

Mars

Josette

Javelas

Henri

Loriette

Sylvain

Fvrier

Jean-Yves

Vous notez que Frdrique Fvrier nest pas concerne puisque, si elle a le mme nom
de famille, elle possde un prnom diffrent.
Comme on enlve les doublons, la requte peut produire lun des rsultats qui suivent :
select distinct (1re solution)
nomP

prnomP

select distinct (2e solution)


nomP

prnomP

Fvrier

Frdrique

Fvrier

Frdrique

Fvrier

Jean-Yves

Mars

Josette

Mars

Josette

Javelas

Henri

Javelas

Henri

Loriette

Sylvain

Loriette

Sylvain

Fvrier

Jean-Yves

Jai laiss lenregistrement conserv en gras : sur les deux, on peut garder le premier ou
le second. Lequel des deux rsultats SQL va-t-il donner ? Cest une question sans objet.
Vous navez qu essayer ! Lordre des enregistrements tant arbitraire dans les tables,
vous ne pouvez ni ne devez tabler sur le fait quun enregistrement sera avant ou aprs
un autre. Si vous voulez imposer un semblant dordre dans les enregistrements, poursuivez le cours !

Exercice 38
Cette requte est absolument identique :
select count (Collection)
from Livre ;
En effet, une requte avec fonction dagrgat ne revoie quun seul enregistrement. Or,
pour avoir un risque denregistrement doublon, il faut en avoir au moins deux ! Ainsi,
mettre distinct ne change absolument rien. Il est donc un peu bte de le mettre. mon
sens, cest une erreur de logique.

Exercice 39
Vous devez avoir crit :
select HeureC
from Consultation
where DateC = 26/08/1996 ;
Je viens de tester cette requte sous Access 2003. Je suis assez tonn car nous nobtenons aucun message derreur. Mais, en tout tat de cause, la requte ne donne aucun
rsultat. Enfin, on obtient un rsultat, qui est : il ny a aucun enregistrement rpondant
36
8 3999 TC PA 00

Quelques complments importants

la requte . Attention, cette phrase est une interprtation du rsultat (un enregistrement vide), elle ne saffiche pas lcran.
Allez voir la suite du cours pour lexplication.

Exercice 40
Vous ne voyez pas ? Si je vous dit 2/5, vous me dites quoi ? 0,4 ? Eh bien, vous avez
raison ! Si je vous dis 2/5/2 ? Eh bien 2/5/2 = (2/5)/2 = 0,4/2 = 0,2.
Bref, 26/08/1996 est une expression mathmatique valant 0,00016283 (26/08/1996 =
26/8/1996 = (26/8)/1996 = 3,25/1996 = 0,00016283).

Exercice 41
Les dates retenues seront postrieures au 31/12/2000 donc au choix :
suprieures strictement au 31/12/2000 ;
suprieures ou gales au 01/01/2001 ;
ce qui donne deux requtes possibles :
select *

select *

from consultation

from consultation

where DateC > #31/12/2000# ;

where DateC >= #01/01/2001# ;

Vous noterez que le sujet ne demandant rien de prcis, je ne me fatigue pas et je renvoie
tous les champs.

Exercice 42
Les consultations de lanne 2000 ont eu lieu du 01/01/2000 au 31/12/2000, ce qui
donne :
select *
from Consultation
where DateC >= #01/01/2000# and DateC <= #31/12/2000# ;
Nous verrons deux autres faons pour faire cela dans la suite du cours.

Exercice 43
Consultations en 2000
Une consultation aura eu lieu en 2000 si son anne est 2000 donc si year (DateC) =
2000. Cela donne :
select *
from Consultation
where year (DateC) = 2000 ;

37
8 3999 TC PA 00

Squence 4

Vous noterez que cette requte est beaucoup plus lisible que celle de lexercice 42. De
plus, elle minimise les risques derreur de rdaction : il ny a plus se creuser la tte pour
choisir les bons oprateurs et connecteurs logiques.
Annes avec au moins une consultation
Pour avoir toutes les annes, noubliez pas le distinct ! En effet, mme si jai 50 consultations en 2000, je ne veux quune seule fois lanne 2000 en rsultat.
select distinct Year (DateC) as [Anne avec consultation(s)]
from Consultation ;
La difficult de cette requte, ctait de penser au distinct.

Exercice 44
Eh bien, pas de difficult particulire :
select count (*)
from Consultation
where DateC= #07/12/2000# and heureC = #12:00# ;
Notez que la requte ne renvoie aucun rsultat sur mon PC. En revanche, si jcris DateC
= #12/07/2000#, cela fonctionne.
En fait, il faut que jcrive la date au format amricain MM/JJ/AAAA. Bien entendu, cela
est en totale contradiction avec le fait quAccess massure quil utilise les rglages dfinis
dans Poste de travail/Panneau de configuration/Options rgionales et linguistiques o
jai naturellement dfini les rglages franais.
Bref, si vous obtenez un rsultat erron, ne vous affolez pas : tentez comme moi de permuter le jour et le mois dans les dates.
Dans un vrai dveloppement dentreprise, il faudrait prendre trs srieusement cela en
compte.
(En fait, ce qui se passe, cest que le moteur Access travaille en interne au format amricain. Et, en tapant une requte ainsi, la conversion nest pas faite.)

Exercice 45
Ma foi, vous devez sans difficult avoir crit :
select NomA
from Animal ;

Exercice 46
Tri mis part, la requte est classique :
select NomA, DateNaissA
from Animal ;

38
8 3999 TC PA 00

Quelques complments importants

Nous voulons la liste trie daprs la date de naissance ; nous aurons donc une clause du
style order by DateNaissA. Seulement, doit-on mettre desc ?
On veut un tri du plus vieux au plus jeune. Or, plus lanimal est vieux, plus il est n il y
a longtemps, donc plus sa date de naissance est petite. Je vous rappelle quune date
antrieure (avant) une autre est dite plus petite.
Si X est n le 07/12/1970 et Y le 15/08/1968, Y est plus vieux et sa date de naissance est
plus petite.
Je veux donc les dates de naissance de la plus petite la plus grande. Cest lordre chronologique standard, il ne faut donc pas mettre desc ! La requte est :
select NomA, DateNaissA
from Animal
order by DateNaissA ;
Testez la requte. Vous remarquerez que les animaux sans date de naissance sont mis en
tte de liste. La valeur Null (signifiant, je vous le rappelle, labsence de valeur) est arbitrairement dfinie comme infrieure toutes les valeurs.
Un bon conseil : lors de requtes o lon vous demande un tri, vrifiez plutt deux fois
quune que votre ordre de tri est correct. Cest dommage dchouer dessus !

Exercice 47
La requte est :
select NomA
from Animal
order by DateNaissA desc ;
Il ny a pas de question se poser pour lordre de tri : comme lordre est le contraire de
celui de lexercice 46, on doit logiquement ajouter desc. La seule autre diffrence avec
la requte prcdente est que je ne renvoie plus DateNaissA dans le select puisque ce
nest plus demand.
Cette requte va-t-elle ou non fonctionner ? Comme je lai dit dans le sujet, tout dpend
du moment de lexcution de la clause order by :
si le tri est effectu alors que lon a tous les champs de la table initiale dans la table
de travail, DateNaissA est encore prsent donc on peut trier les enregistrements en
fonction des valeurs de ce champ ;
en revanche, si lon trie aprs avoir supprim les champs non demands il ne reste
plus que NomA ! Impossible donc de trier selon un autre champ.
Bon. Il est temps de tester ! (Faites-le)
Eh bien, cela fonctionne. Est-ce une surprise ? Ma foi, oui et non : il ny avait aucune
raison de supposer que ce serait lune ou lautre des solutions qui serait retenue : elles
taient toutes les deux plausibles.

Cest encore une erreur bte mais classique ; mais bte.


39
8 3999 TC PA 00

Squence 4

Cela dit, il est sympathique que ce soit la premire version qui fonctionne car cest la plus
gnrale (permettant de faire le plus de choses). En effet, cela nous donne lopportunit
de trier les donnes sur des champs absents du rsultat final. Que cela soit une bonne
ide de faire ce genre de chose cest un autre problme !
Cet exercice nous permettra de donner le fonctionnement des requtes avec tri.

Exercice 48
En demandant une liste classe par prix TTC, je sous-entends une liste classe par prix TTC
croissant. Sans prendre en compte le tri, la requte est classique :
select NomM, PrixM*1.196 as [Prix TTC]
from Mdicament ;
Attention bien utiliser le point dcimal (1.196) et non la virgule (1,196). Pourquoi ? Car
avec une virgule, SQL interprterait la clause select comme contenant trois champs puisque
la virgule est le sparateur. Ces champs seraient NomM, PrixM*1 et 196, ce dernier ayant
comme libell Prix TTC.
Vous devez vous douter de lintrt de cet exercice : peut-on trier une requte selon un
champ calcul, et si oui, comment ?
Avant de vous donner la rponse, nous allons voir quil y avait moyen dcrire la requte
sans se poser la moindre question. Il suffisait de faire preuve de bon sens. En effet, si le
prix HT du produit P1 est suprieur celui du produit P2, alors le prix TTC de P1 est galement suprieur celui de P2.
Ce sont des mathmatiques de base :
PrixHTP > PrixHTP PrixHTP *1,196 > PrixHTP *1,196 PrixTTCP > PrixTTCP
1

Ainsi, trier selon le prix TTC ou le prix HT revient absolument au mme ! Et, comme le
prix HT est un champ de la table, nous navons plus de question nous poser. On pouvait
donc crire :
select NomM, PrixM*1.196 as [Prix TTC]
from Mdicament
order by PrixM ;
(Je vous rappelle que le champ sur lequel on trie nest pas ncessairement prsent dans le
select voir lexercice prcdent.)
Bien. Cette astuce tant vue, tchons de rpondre la question : peut-on trier selon un
champ calcul ? Pour le moment, vous devez avoir lesprit deux solutions diffrentes
venant de deux points de vue diffrents.
1. PrixM*1.196 est le champ calcul selon lequel on veut trier ? Et bien, on va ajouter
order by PrixM*1.196 ! Cela donne :
select NomM, PrixM*1.196 as [Prix TTC]
from Mdicament
order by PrixM*1.196 ;

Alors que, en toute rigueur, il faudrait utiliser la virgule puisque cest le sparateur officiel en France.
Mais bon, cette prise en compte des normes franaises nexiste que dans Excel.
40
8 3999 TC PA 00

Quelques complments importants

2. Comme le champ calcul PrixM*1.196 est dot dun libell ainsi que je lai conseill
maintes reprises, je peux tout aussi bien utiliser ce dernier pour ma clause order
by :
select NomM, PrixM*1.196 as [Prix TTC]
from Mdicament
order by [Prix TTC] ;
(Je vous rappelle lobligation de mettre des crochets autour des noms de champs faisant plusieurs mots.)
Que donnent ces deux requtes ? Testez-les ! La premire fonctionne, pas la seconde (
lexcution, vous obtenez un message entrez la valeur du paramtre nous aborderons cela un peu plus loin dans la squence).
Cela va nous permettre de dterminer quand la clause order by est excute. En effet,
nous pouvons trier selon un champ calcul, mais en crivant sa valeur (par exemple
PrixM*1.196). Si lon utilise le libell de ce champ calcul (qui est dfini dans le select),
cela ne fonctionne plus. Cela nous montre que la clause order by est excute avant le
select, ce dont on se doutait puisque lon a encore accs aux champs qui sont supprims
par le select.

Exercice 49
La requte est la suivante :
select NomP, PrnomP
from Proprtaire
order by NomP, PrnomP ;
De faon assez logique, je trie les donnes dans lordre o elles apparaissent dans le
select.
Testez cette requte ; comparez le rsultat avec celui obtenu lorsque lon ne triait que
selon le nom. Vous remarquerez que les trois Fvrier (Frdrique et les deux Jean-Yves)
sont maintenant tris entre eux par ordre alphabtique sur leur prnom.
En effet, daprs mon explication sur le tri multi-champs, ce nest que lorsque les valeurs
sont identiques sur le premier champ (ici, le nom) que lon trie sur le second champ (ici, le
prnom). Jaurais pu rajouter un troisime champ (la ville ou autre) qui aurait permis de
trier les deux homonymes Jean-Yves Fvrier ayant la mme valeur pour les deux champs
de tri.

Exercice 50
Rien de difficile, je voulais juste vous faire trier sur un champ calcul. On obtient :
select NomM, PrixM*1.196 as [Prix TTC]
from Mdicament
order by 2 ;
Cest tout de mme plus lisible que order by PrixM*1.196 !

41
8 3999 TC PA 00

Squence 4

Exercice 51
Cest un exercice pnible car il me faut crire trois requtes presque identiques, une par
tatouage :
select NomA
from Animal
where Tatouage = "ZEN245";
select NomA
from Animal
where Tatouage = "OIU115" ;
select NomA
from Animal
where Tatouage = "TOT020" ;
lexcution de la troisime requte, vous remarquerez que lanimal correspondant
nest pas dans votre base de donnes.
Si je vous avais demand didentifier cinquante tatouages et non trois ? Quel cauchemar !
Nous allons voir dans la suite du cours comment faire cela de faon plus raisonnable.

Exercice 52
Ce nest pas trs dur. Voici un petit rsum du cours indiquant lexcution de la requte :
1. Le from : produit cartsien.
2. le where : pour chaque enregistrement, on teste la condition logique et on ne
garde que les enregistrements qui la vrifient.
Avant toute chose, SQL cherche les paramtres et vous demande leur valeur. Nous avons
le paramtre [Tatouage identifier]. Access va donc ouvrir une bote de dialogue et
vous demander de rentrer une valeur pour ce paramtre. Dans notre cas, vous rentrez
ZEN245.
La requte excute sera donc :
select NomA
from Animal
where tatouage = "ZEN245" ;
Deuxime excution de la requte : vous entrez TOTO020 comme valeur du paramtre.
La requte excute sera donc :
select NomA
from Animal
where tatouage = "TOTO020" ;
Aucun enregistrement nayant cette valeur dans Tatouage, le test nest jamais vrifi. La
requte ne renvoie donc rien.

42
8 3999 TC PA 00

Quelques complments importants

Conclusion de lexercice :
Vous ne saisissez quune fois la valeur du paramtre. Cette valeur sera utilise tout au
long de lexcution de la requte donc pour tous les enregistrements et cest trs bien
ainsi : supposez une table de 50 000 enregistrements o SQL vous demanderait une
valeur du paramtre pour chacun deux !
Corollaire de cela : il est impossible de donner une valeur de paramtre par enregistrement.

Exercice 53
1. Nous allons modifier la 4e requte de lexercice 35 : donnez lhistorique des
traitements subis par un animal donn (donc fourni en paramtre).
Il suffit dadapter un tout petit peu la clause where en changeant la constante Nouki en
paramtre (en gras dans la requte) :
select DateC, HeureC, NomV, PrnomV, NomS
from Animal A, Vtrinaire V, Soin S, Pratiquer P, Consultation C
where (A.NumA = C.NumA) and (C.NumV = V.NumV) and (P.NumC = C.NumC)
and (S.NumS = P.NumS) and NomA = [Nom de lanimal] ;
2. Donnez le prix des consultations ayant eu lieu un jour et une heure donns.
Quand je dis un jour et une heure donns ce sont videmment des paramtres et cest
lutilisateur qui va les fournir. La requte ne doit poser aucun problme :
select PrixC
from Consultation
where DateC = [Date] and HeureC = [Heure] ;
(En testant, mfiez-vous de lventuel problme de la saisie de la date jj/mm/aaaa ou
mm/jj/aaaa.)

Exercice 54
Cet exercice est beaucoup moins vident quil ny parat. Sil vous a paru trs facile,
relisez-vous !
Premire requte
select Coucou
from Livre ;
Recherche des paramtres ventuels. Il y a Coucou ; en effet, ce champ ne fait pas partie
de la table Livre. SQL demande la valeur de ce paramtre ; on rentre Salut !. La requte
excute est alors :
select "Salut !"
from Livre ;
Une seule table dans le from, pas de clause where je vous gte. Tous les enregistrements de Livre sont conservs ; et les champs ? lesquels on garde ? Uniquement un
champ calcul, la constante Salut ! Comme cest un champ calcul sans libell, son nom
est Exprxxx.
43
8 3999 TC PA 00

Squence 4

Le rsultat est donc un seul champ et 2 321 enregistrements (le nombre de livres) avec la
valeur Salut ! pour chaque enregistrement.
Seconde requte
select *
from Auteur
where NomAuteur = "Stendhal" ;
On effectue la recherche des paramtres ventuels. Il y en a un ! En effet, le champ contenant le nom de lauteur dans Auteur est Nom. NomAuteur tant inconnu, cest donc
un paramtre. SQL vous demandera sa valeur, et l, deux cas possibles :
1. Vous entrez la valeur Stendhal.
La clause where est alors where "Stendhal" = "Stendhal". En dautres termes, la condition est quivalente 2 = 2, soit la constante vrai. Chaque enregistrement vrifie
donc trivialement le test. La requte revient :
select *
from Auteur ;
Le rsultat est donc la table Auteur.
2. Vous entrez autre chose que Stendhal, par exemple Nina.
La clause where est alors where "Nina" = "Stendhal". En dautres termes, la condition
est quivalente 3 = 2, soit la constante faux. Aucun enregistrement ne vrifie donc
le test. Le rsultat de la requte est alors rien (aucun enregistrement).
Si vous avez trouv cela, bravo !

Exercice 55
Les deux premires requtes sont simples :
select count (*) as [Nbr livres]

select count (*) as [Nbr auteurs]

from Livre ;

from Auteur ;

En revanche, pour la troisime impossible de lcrire pour le moment ! En effet, pour


avoir la fois les informations lies aux livres et aux auteurs, vous devez faire un produit
cartsien des deux tables puis une jointure. Vous perdez donc le nombre dauteurs.

Exercice 56
Supposons que vous ayez sauvegard les deux premires requtes sous les noms NbrLivres
et NbrAuteurs. Comme ces requtes possdent des fonctions dagrgat, elles nont quun
enregistrement. Effectuer leur produit cartsien revient par consquent les concatner.
Il ny a rien dautre faire !
La requte est :
select *
from NbrLivres, NbrAuteurs ;
Avouez que cest fort simple !

44
8 3999 TC PA 00

Quelques complments importants

Dans lexercice 36, nous navions pas pu rcuprer le nombre de collections car
count (distinct Collection) ne fonctionne pas sous Access. Nous allons donc passer par
deux requtes. La premire renverra les collections (avec un distinct) et la seconde comptera leur nombre.
Appelons ListeCollections la requte suivante :
select distinct Collection
from livre ;
Le nombre de collections sera alors le rsultat de :
select count(*) as [Nombre de collections]
from ListeCollections ;

Exercice 57
Pas de difficult particulire. On obtient :
select NomA
from Animal A, Consultation C
where (A.NumA = C.NumA) and (DateC >= #01/03/1998#) and (DateC <= #01/07/1998#) ;
et :
select NomM, PrixM
from Mdicament
where (PrixM >= 6) and (PrixM <= 15)
order by 2 ;
Vous noterez cependant :
1. Il faut utiliser des comparateurs larges (<= et >=) et non stricts (< ou >) dans les
deux requtes vu la formulation du sujet : sans prcision contraire, les comparateurs doivent toujours tre larges.
2. Il ne faut pas se tromper dans le sens des comparateurs avec les dates (erreur bte
mais classique mais bte).
3. Comme je trie par prix (seconde requte), je renvoie galement le prix des mdicaments pour que lutilisateur comprenne mon tri.

Exercice 58
Ce nest pas difficile si vous tes rigoureux.
Premire requte :
select NomA
from Animal A, Consultation C
where (A.NumA = C.NumA) and (DateC between #01/03/1998# and #01/07/1998#) ;

45
8 3999 TC PA 00

Squence 4

Deuxime requte :
select NomM, PrixM
from Mdicament
where PrixM between 6 and 15
order by 2 ;
Troisime requte :
select NomP
from Propritaire
where NomP between "F" and "L" ;
Nous sommes daccord que cela fonctionne car, daprs lordre alphabtique :
F < Fvrier < G < H < I < J < Javelas < K < L < Loriette
On rcupre donc Fvrier et Javelas. Comme on na pas prcis distinct, on rcupre les
trois Fvrier.

Exercice 59
Impossible dutiliser between car les valeurs ne sont pas contigus. Il faut donc crire une
tripote de conditions relies par un or :
select NomR
from Race
where (Poids = 7) or (Poids = 2.5) or (Poids = 20) ;
(Attention : en SQL, le nombre 2,5 scrit 2.5)

Exercice 60
Pffft ! Sans problme :
select NomR
from Race
where Poids in (7, 2.5, 20) ;

Exercice 61
Bien. Comme il ny a pas de type de mdicaments, on ne peut pas faire quelque chose du
style where NumType = 5 (5 tant alors le numro du type vermifuge). Il faut connatre
le nom des diffrents vermifuges et les tester.
select NomM, PrixM
from Mdicament
where (NomM = "Vermifuge pte") or (NomM = "Vermifuge cachet") ;
(notez bien le or).

46
8 3999 TC PA 00

Quelques complments importants

Exercice 62
Nous voulons tous les mdicaments dont le nom commence par Vermifuge, soit :
select NomM, PrixM
from Mdicament
where NomM like "Vermifuge*" ;

(ou "Vermifuge *" avec un espace avant le *)

Exercice 63
En dautres termes, je veux les animaux qui nont aucune valeur pour tatouage :
select NomA
from Animal
where Tatouage is null ;

47
8 3999 TC PA 00

Travaux dirigs 1

1. Donnez la liste des salaris.


select NomS, PrnomS
from salari ;
Comme le sujet ne prcise pas les informations ncessaires, un select * tait acceptable.
2. Donnez la liste des salaris embauchs durant une anne donne.
select NomS, PrnomS
from salari S, contrat C
where (C.NumS = S.NumS) and (Year(DateSig) = [Anne dembauche]) ;
Notez que une anne donne fait rfrence un paramtre. Pour extraire lanne dune date,
on utilise la fonction Year.
3. Donnez les villes o habitent les salaris.
select distinct Ville
from salari ;
Distinct obligatoire !
4. Donnez le nombre de jours de congs auxquels un salari donn a droit au titre de
son contrat actuel (CDI seulement).
select (Date()-DateSig)/30*2.5 as [Jours de cong acquis]
from salari S, contrat C
where (C.NumS = S.NumS) and (NomS = [Nom du salari]) and (DateFin is Null) ;
2,5 jours de congs par mois de travail ; je calcule donc le nombre de jours de travail et je divise
par 30 pour obtenir le nombre de mois. Enfin, le contrat CDI actuel est le seul dont la date de
fin est nulle (non renseigne). Je nai donc pas utiliser TypeContrat.
5. Combien de contrats de moins de trois mois (termins ou non) ont t signs ?
select count(*) as [Nbr contrats de moins de trois mois]
from contrat
where DateFin-DateSig < 90 ;
Je renvoie galement les CDI qui nont dur que trois mois (cest rare).
6. Donnez le total des jours de congs pris par un salari donn (tous contrats confondus).
select sum(DureC) as [Jours de cong]
from cong Cg, contrat C, salari S
where (Cg.NumC = C.NumC) and (C.NumS = S.NumS) and (NomS = [Nom du salari]) ;

49
8 3999 TC PA 00

Travaux dirigs

7. Donnez le total des jours dabsence pris par un salari donn (tous contrats confondus).
select sum(DureA) / 2 as [Jours dabsence]
from absence A, contrat C, salari S
where (A.NumC = C.NumC) and (C.NumS = S.NumS) and (NomS = [Nom du salari]) ;
Attention au pige : je demande un nombre de jours et les dures dabsence sont dcomptes en
demi-journes. Il faut donc diviser par deux.
8. Quels salaris ont eu des absences non autorises au cours du mois courant ?
select NomS
from salari S, contrat C, typeAbsence T, absence A
where (S.NumS = C.NumS) and (C.NumC = A.NumC) and
(A.NumTA = TA.NumTA) and (AutorisTA = false) and
(Month(DateDbut) = Month(Date())) and
(Year(DateDbut) = Year(Date())) ;
Au lieu de AutorisTA = false, on pouvait crire not(AutorisTA). Cest plus lgant. Attention
lexpression le mois courant . Si nous sommes le 08/11/2007, le mois courant nest pas
novembre, mais novembre 2007. Si lon ne prend pas en compte lanne, on aura le cumul des
absences pour tous les mois de novembre (2007, 2006, 2005).
9. Salaire mensuel brut moyen des salaris.
select avg(SalaireBrutMens) as [Salaire moyen]
from contrat ;
10. Salaires mensuels bruts maximum et minimum des CDI signs cette anne.
select min(SalaireBrutMens) as [Salaire min],
max(SalaireBrutMens) as [Salaire max]
from contrat C, typeContrat T
where (C.NumTC = T.NumTC) and (LibellTC = "CDI") and (Year(DateSig)=Year(Date())) ;
11. Salaire annuel net du contrat numro 144. On supposera que le salaire net reprsente 80 % du brut et que le salari touche une participation annuelle gale 95 %
de son salaire brut mensuel.
select SalaireBrutMens*0.8*12 + SalaireBrutMens*0.95 as [Salaire net annuel]
from contrat
where NumC = 144 ;

50
8 3999 TC PA 00

Travaux dirigs

Le salaire net annuel, cest le salaire net mensuel (SalaireBrut*0.8) multipli par 12 (les 12 mois
de lanne) plus lintressement (SalaireBrut*0.95).
Si vous avez ralis ces requtes sans trop de problmes, vous avez parfaitement assimil
le cours. Bravo ! Il ne vous reste plus qu attaquer la suite.
Je prcise que le rel modlis ntant pas simple, les questions poses pouvaient parfois
tre un peu ambiges. Ne vous traumatisez donc pas si vous avez eu une lecture diffrente
du sujet. Les divergences dinterprtations taient possibles dans ce TD.

51
8 3999 TC PA 00

Você também pode gostar