|
Chap.0:Présentation Chap.2:Les Doublons Chap.4:Clause Order Chap.6:Les Jointures Chap.8:Les Corrélations |
Chap.1:Intérrogation simples Chap.3:Clause WHERE Chap.5:Valeur Nulle Chap.7:Les Imbrication |
Le SQL est un langage d'intérrogation qui travail sur des tables de données. Ces tables de données sont généralement dans des fichiers. Tous les exemples que je vais vous donner utiliseront les tables suivantes. Je vous conseil donc de bien comprendre les relations entres les tables avant de vous lancer dans les prochains chapitres.
Premièrement, il faut comprendre que S#, P# et J# sont chacuns Clé primaire dans leur table respective. C'est-à-dire qu'ils doivent être unique dans leur table. Par exemple, il ne pourrait pas y avoir deux fois des records portant le numéro de pièce P2 dans la table de pièce. La table S contient des donnés quelconque sur des fournisseurs. La table P contient des donnés quelconque sur des pièces qui sont fournis par 1 ou plusieurs fournisseurs. La table J elle contient des informations sur des projets quelconques. Ces projets ont besoins de pièces qui sont fournis par les fournisseurs de la table S. Les relations entre ces tables sont assez simple. Chaque fournisseurs S# fournissent un nombre quelconque de pièces P# à un projet J# quelconque. Cela est représent par la table SPJ. Par exemple, les 2 premiers records de la table SPJ sont interprétés de la facon suivante: Le fournisseur S1 livre 25 pièces P2 au projet J2. Le fournisseur S1 livre également 9 pièces P4 au projet J3.
Une requête SQL dans son plus simple se résume par une clause Select, ou l'on spécifi les champs désirés, puit d'une clause From, ou l'on doit spécifier le nom de la table qui contient les champs désirés. Par exemple, si nous voulons avoir les caractéristiques de toutes les fournisseurs de la table Fournisseurs (F): Select s#, snom, status, ville From S Cette requêtte retournerait: S1, Joe, 20, Terrebonne S2, Bin, 15, Mascouche S3, Min, 30, Montréal Lorsque nous voulons tous les champs d'une table, nous pouvons les remplacer par une étoile (*) au niveau du Select: Select * From S
Si nous voulons les p# qui sont dans la table SPJ, donc ceux qui ont été livrées, nous ferons: Select p# From SPJ mais il y a un petit problème. Supposont que la table SPJ contienne les données suivantes: s# p# j# Quantité S1, P1, J4, 200 S2, P1, J6, 150 S3, P2, J3, 230 S3, P4, J5, 140 S4, P5, J1, 45 Le Select précédant retournerait: P1, P1, P2, P4, P5 Comme vous pouvez le constater, la pièce P1 est retourné 2 fois car elle est livrée par le fournisseur S1 au projet J4 et elle est aussi livrée par le fournisseur S2 au projet J6. C'est ce qu'on appele un Doublon. Nous pouvons éliminer ces doublons en utilisant DISTINCT. ex.: Select DISTINCT(p#) From P Les pièces retournées seraient alors: P1, P2, P4, P5
Lorsque nous avons des critères de sélection, nous devons avoir recoure à la clause WHERE. Par exemple, si nous voulons toutes les pièces livrées par le fournisseur S1, nous ferons: Select p# From SPJ Where s# = 'S1' Nous aurions pu également faire: Select DISTINCT(p#) From SPJ Where s# = 'S1' Car il se pourrait que le fournisseur S1 ait livré, par exemple, une pièce P1 au projet J3 et la même pièce P1 au projet J4. Nous aurions alors un Doublon, c'est pourquoi nous avons mis un DISTINCT au Select. Autres exemples: -On veut les numéros ainsi que les noms des pièces qui sont conservées à Londres: Select p#, pnom From P Where ville = 'Londres' -On veut des pièces qui sont de couleurs Rouge et qui sont entreposées à Paris: Select p# From P Where couleur = 'Rouge' And ville = 'Paris' N.B.: Avec la clause Where, nous pouvons utiliser And, Or et Not. -On veut le nom des pièces et leur poids en gramme. N.B.: 1 lb = 454 grammes Select pnom, poids * 454 From P -On veut les numéros de pièces dont leur poids est entre 10 et 30: Select p# From P Where poids BETWEEN 10 AND 30 Notez que le contraire de BETWEEN est NOT BETWEEN.
Avec SQL, il nous est possible de faire des requêtes en ordre croissant ou décroissant. C'est-à-dire que nous pouvons spécifier que la liste retounée par le Select soie dans l'ordre demandée. Par exemple, si nous voulons avoir le status des fournisseurs en ordre croissant, nous ferons: Select status From S Order BY status ASC La requête suivante retournerait: 10,20,25 Autres exemples: -On veut le nom des fournisseurs Parisiens par ordre décroissant de nom: Select snom From S Where ville = 'Paris' Order BY snom DESC -On veut le nom des pièces dont le numéro de la pièce est > 100, dont sa couleur est Rouge, le tout en ordre croissant de poids et en ordre décroissant de numéro de pièces: Select pnom From P Where p# > 100 And couleur = 'Rouge' Order BY poids ASC, p# DESC
Dans le merveilleux monde des bases de données relationnelles, il peut arriver qu'un champ d'une table n'est pas de valeur... qu'il soit Nulle. Nous pourrions par exemple avoir dans la table fournisseur, un record comme suit: S5, Smith, null, Londres Suite à cela, si nous voulions le noms des fournisseurs dont le status est inconnue, la requête qui suit ne serait pas bonne: Select snom From S Where status IS NULL Le 'IS NULL' n'est pas bon car lorsqu'on parle de valeur Nulle, on parle d'une valeur qui nous aient inconnue. Il faudrait plutot faire: Select snom From S Where satatus < 50 OR >= 50
Si nous voulons les s# des fournisseurs qui ont livré la pièce P1, nous procéderont
comme suit:
Select s#
From SPJ
Where p# = 'p1'
Mais les choses se compliquent si nous décidons d'avoir le nom des fournisseurs, au
lieu du numéro des fournisseurs car la table SPJ ne contient pas le s# des
fournisseur. Nous devrons donc avoir recourt aux Jointures. Supposons que nous
avons les recors suivant:
Table SPJ: Table S:
S# P# J# QTE S# SNOM
s1 p1 j1 200 s1 Smith
s1 p2 j3 400 s2 Jones
s2 p1 j4 500 s4 Josbin
s3 p5 j6 600
La jointure de la table SPJ avec la table S donnera:
SPJ S
S# P# J# QTE S# SNOM
s1 p1 j1 200 s1 Smith
s1 p1 j1 200 s2 Jones
s1 p1 j1 200 s4 Josbin
s1 p2 j3 400 s1 Smith
s1 p2 j3 400 s2 Jones
s1 p2 j3 400 s4 Josbin
s2 p1 j4 500 s1 Smith
s2 p1 j4 500 s2 Jones
s2 p1 j4 500 s4 Josbin
s3 p5 j6 600 s1 Smith
s3 p5 j6 600 s2 Jones
s3 p5 j6 600 s4 Josbin
Donc pour avoir le nom des fournisseurs qui ont livré P1, nous ferons:
Select Sname
From SPJ,S <- Plus d'une table : jointure
Where spj.s# = s.s#
And p.p# = 'P1'
Autres exemples:
-On veut la ville des fournisseurs des la pièce P4 au projet J3
Select Ville
From s,spj
Where s.s# = spj.s#
And spj.j# = 'J3'
And spj.p# = 'P4'
-On veut toutes les paires P#,S# tel que la ville de la pièce est la même
que la ville du fournisseur:
Select p#, s#
From p,s
Where s.ville = p.ville
-On veut les paires S#,S# tel que les 2 fournisseurs sont dans la même ville:
Select SA.s#, SB.s#
From s SA, s SB <- Jointure de 2 tables identiques
Where SA.ville = SB.ville
And SA.s# < SB.s#
Ici, vous vous demendez surment pourquoi le <. Supposons que la table
de fournisseur 'S' contienne 2 fournisseurs de même ville:
S# SNOM STATUS VILLE
S1 Joe Bin 10 Terrebonne
S2 Elvis G. 15 Terrebonne
Une jointure de cette table par la même donnera: (Limitons-nous aux
numéros de fournisseurs!)
S1 S1
S1 S2
S2 S1
S2 S2
Sachant que nous voulons 2 fournisseurs DIFFéRANT de la même ville,
S1 < S1 Faux
S1 < S2 Vrai <- Seul cette valeur sera retournée
S2 < S1 Faux
S2 < S2 Faux
En procédant de cette facon, nous évitons que la requête retourne un
même fournisseur (S1 < S1) et qu'elle retourne 2 fois la même chose
soie S1 S2
S2 S1
-On veut le nom du fournisseur et le nom du projet pour toutes les livraisons
de la pièce 'P1':
Select Snom, Jnom
From S, J, SPJ
Where SPJ.p# = 'P1'
And SPJ.j# = J.j#
And SPJ.s# = S.s#
-On veut le nom des fournisseurs de Londres qui ont livré la pièce 'P1':
Select Snom
From SPJ, S
Where SPJ.s# = S.s#
And SPJ.p# = 'P1'
And S.Ville = 'Londres'
-On veut le nom des fournisseurs de Londres qui ont livré des pièces à un
projet de Londres:
Select Snom
From S, J, SPJ
Where S.s# = SPJ.s#
And S.Ville = 'Londres'
And J.j# = SPJ.j#
And J.Ville = 'Londres'
Le "Structured" dans SQL vient du fait qu'on peut imbriqués des Select. Si nous voulons les noms des fournisseurs qui ont livré la pièce 'P2': Par jointure: Select Snom From SPJ, S Where SPJ.s# = S.s# And SPJ.p# = 'P2' Pour avoir l'équivalent sous forme imbriqué, nous ferons: Select Snom From S Where s# IN(Select s# From SPJ Where p# = 'P2') Ici, la requête commence par exécuter le bloc IN(Select s#...) qui retourne l'ensemble des fournisseurs de la Pièce 'P2'. Ensuite, pour chaques numéro de fournisseur, le 'Select Snom...' va vérifier si le s# de la table S fait partie de la liste de s# retourné par le bloc IN(Select s#...). Il faut donc comprendre que le bloc IN(...) n'est pas exécuté pour chaque s# du la table S mais plutot exécuté qu'une seule fois. Par exemple, si le bloc IN(...) retournerait S1, S3 et S4, on pourrait dire: Select Snom From S Where s# IN( S1, S3, S4) <- Est-ce que le s# fait partie de la liste du IN(...)? Autres exemples: -On veut les noms des fournisseurs qui ont livré la pièce P2 au projet J1: Par Jointure Par Imbriquation Select Snom Select Snom From SPJ, S From S Where SPJ.s# = S.s# Where s# IN(Select s# And SPJ.p# = 'P2' From SPJ And SPJ.j# = 'J1' Where p# = 'P2' And j# = 'J1') -On veut le nom des fournisseurs qui ont livré des pièces à un projet de Londres: Par Jointure Par Imbriquation Select Snom Select Snom From S, SPJ, J From S Where SPJ.s# = S.s# Where s# IN(Select s# And SPJ.j# = J.j# From SPJ, J And J.Ville = 'Londres' Where SPJ.j# = J.j# And J.Ville = 'Londres') Autre facon d'imbriquer la requête: Select Snom From S Where s# IN(Select s# From SPJ Where j# IN(Select j# From J Where J.Ville = 'Londres')) -On veut les noms des fournisseurs qui ont livré des pièces Rouge à des projets de Londres: Par Jointure: Select Snom From S, P, J, SPJ Where SPJ.s# = S.s# And SPJ.j# = J.j# And SPJ.p# = P.p# And P.couleur = 'Rouge' And J.Ville = 'Londres' Par Imbriquation: Select Snom From S Where s# IN(Select s# From SPJ Where j# IN(Select j# From J Where Ville = 'Londres') And p# IN(Select p# From P Where couleur = 'Rouge')) -On veut les noms des fournisseurs de Londres qui ont livré des pièces de Londres à des projets de Londres: Par Jointure: Select Snom From S Where s# IN(Select s# From SPJ Where p# IN(Select p# From P Where Ville = 'Londres') And j# IN(Select j# From J Where Ville = 'Londres')) And Ville = 'Londres' -On veut les noms des fournisseurs qui ont livré au moins une pièce qui à aussi été livré par S2: Select Snom From S Where s# IN(Select s# From SPJ Where p# IN(Select p# From SPJ Where s# = 'S2')) Par Imbriquation: Select DISTINC(Snom) From S, SPJ SPJ1, SPJ SPJ2 Where S.s# = SPJ1.s# And SPJ2.s# = 'S2' And SPJ1.p# = SPJ2.p#
Si nous voulons les noms des fournisseurs qui ont livré la pièce P2, nous ferons par jointure: Select Snom From S, SPJ Where S.s# = SPJ.s# And SPJ.p# = 'P2' Par imbriquation, nous ferons: Select Snom From S Where s# IN(Select s# From SPJ Where p# = 'P2') Par Corrélation, nous devrons procéder comme suit: Select Snom From S Where 'P2' IN(Select p# From SPJ Where SPJ.s# = S.s#) Même si le code SQL de l'imbriquation ressemble beaucoup à au code de la corrélation, la différence est grande. Comme je l'ai dit précédemment, le bloc IN(...) de l'imbriquation est exécuté une seule fois pour tous les records contenus dans la table S. Ce bloc retourne une liste et ensuite, la requête vérifie si le s# de chaque records de la table S est dans cette liste. La grande différence avec la corrélation est que le bloc IN(...) sera exécuté pour chaques record de la table S. Dans notre cas, le bloc IN(...) retournerait toutes les SPJ.p# dont SPJ.s# correspondrait à S.s# Autres examples: -On veut le nom des pièces qui ont été livré à des projets de londres: Par Jointure: Select Pnom From P, J, SPJ Where SPJ.p# = P.p# And SPJ.j# = J.j# And J.ville = 'Londres' Par Imbrication: Select Pnom From P Where p# IN(Select p# From SPJ Where j# IN(Select j# From J Where ville = 'Londres')) Par Corrélation: Select Pnom From P Where 'Londres' IN(Select ville From J, SPJ Where SPJ.j# = J.j# And SPJ.p# = P.p#) -On veut le nom des fournisseurs qui ont livré la pièce P2: Par Jointure: Select Snom From S, SPJ Where S.s# = SPJ.s# And SPJ.p# = 'P2' Par Imbrication: Select Snom From S Where s# IN(Select s# From SPJ Where p# = 'P2') Par Corrélation: Select Snom From S Where P2 IN(Select p# From SPJ Where SPJ.s# = S.s#) -On veut le nom des fournisseurs qui n'ont pas livré la pièce P2: Par Imbriquation: Select Snom From S Where s# not IN(Select s# From SPJ Where SPJ.p# = 'P2') Par Corrélation: Select Snom From S Where P2 not IN(Select p# From SPJ Where SPJ.s# = S.s#) -On veut les noms les fournisseurs qui ont livré au moins une pièce qui n'est pas P2: Select Snom From S Where s# IN(Select s# From SPJ Where SPJ.p# ¬= 'P2') Dans ce cas ci, il ne faut pas oublier que la table SPj peut avoir la forme suivante: ex.: S1 P3 J4 S1 P2 J3 -On veut les numéros des fournisseurs qui ont livré au moins une pièce que S1 à livré: Select s# From SPJ spja Where S1 IN(Select s# From SPJ spjb Where spja.p# = spjb.p#) -On veut le nom des fournisseurs qui on livré au moins une pièce à un projet de la même ville: Par jointure: Select Snom From S, SPJ, J Where S.s# = SPJ.s# And J.j# = SPJ.j# And S.ville = J.ville Par imbriquation: Select Snom From S Where s# IN(Select s# From SPJ Where j# IN(Select j# From J Where J.ville = S.ville)) -On veut les numéros des pièces qui on été livrées par plus d'un fournisseur: Par imbriquation: Select p# From SPJ spja Where p# IN(Select p# From SPJ spjb Where spja.s# ¬= spjb.s#) Par Jointure: Select p# From SPJ spja, SPJ spjb Where spja.p# = spjb.p# And spja.s# < spjb.s# -On veut les numéros des fournisseurs qui on la même ville que le fournisseur S1: Par jointure: Select s# From S s1, S s2 Where s1.s# = 'S1' And s1.ville = s2.ville And s2.s# ¬= 'S1' Par Corrélation: Select s# From S s1 Where S1 IN(Select s# From S s2 Where s1.ville = s2.ville)