Chapitre 21 : les opérations ensemblistes en SQL
1 - Introduction
Le langage SQL permet de réaliser sur un groupe de deux tables les trois
opérations de base de la théorie des ensembles, c'est à dire :
De ces trois opérations, seule l'union présente vraiment de l'intérêt. Si, dans les
exposés relatifs à SQL, on regroupe généralement les trois opérations
ensemblistes, c'est pour se conformer à une logique mathématicienne. Comme
nous le verrons dans la suite de ce chapitre, l'intersection et la différence sont en
fait des requêtes multi-tables particulières, que l'on peut réaliser même si l'on ne
dispose pas d'une commande spécifique -- ce qui est effectivement le cas
lorsqu'on utilise le SGBD Access.
La requête union, par contre, est quasi irremplaçable : elle seule permet de mettre
deux tables bout à bout en leur faisant jouer des rôles identiques, et en éliminant
systématiquement les doublons. Certes, la requête ajout permet d'ajouter une
table à une autre, mais dans ce cas les deux tables ne jouent pas le même rôle, et
l'élimination des doublons -- si elle s'avère nécessaire -- requiert soit la création
d'un index multi-champ, soit un traitement ultérieur (regroupement).
A ce chapitre nous rajouterons un paragraphe concernant le produit cartésien de
deux tables, requête qui n'est utilisée que très rarement et dans des cas très
spécifiques.
Comme pour les autres chapitres de ce tutoriel (ou tutorial, ou cours en ligne),
nous utiliserons le SGBD Access comme support pratique.
2 - L'union de deux tables
L'union de deux tables est une une feuille de données (ou une table) contenant
chaque ligne de la première table et chaque ligne de la seconde table. Les lignes
communes aux deux tables ne sont conservées qu'en un seul exemplaire, c'est à
dire que l'opération d'union élimine les doublons. Les champs que l'on fait
correspondre dans les deux tables n'ont pas besoin de porter les mêmes noms ni
de se présenter dans le même ordre -- ni même de posséder le même type de
donnée si la transposition est possible (une date en texte, par exemple).
Exemple 1. La figure ci-dessous illustre l'opération d'union dans le cas simple
les champs portent le même nom, possèdent les mêmes propriétés, et sont situés
dans le même ordre.
nom
prénom
Chose
Jules
Machin
Pierre
Truc
Patrick
union
nom
prénom
Pouf
Jean
Chose
Jules
=
nom
prénom
Chose
Jules
Machin
Pierre
Pouf
Jean
Truc
Patrick
Table1
Table2
Résultat
Il n'existe pas dans Access d'interface graphique permettant de créer une requête
Union. Il faut donc écrire soi-même le code SQL requis. Pour ouvrir l'éditeur de
requêtes SQL, nous sélectionnons l'objet "Requêtes" dans la fenêtre "Base de
données", nous n'introduisons aucune table dans l'interface graphique de
définition des requêtes, et nous basculons en mode SQL.
Si notre base contient les deux tables précitées, nous pouvons exécuter la requête
SQL suivante, contenant l'opérateur UNION :
SELECT nom, prénom
FROM Table1
UNION
SELECT nom, prénom
FROM Table2;
A l'exécution de la requête, nous constatons qu'une feuille de données est créée,
qui rassemble le contenu des deux tables, et en élimine les doublons. Si nous
enregistrons la requête (sa structure, pas son contenu), Access fait précéder son
nom de l'icône pour rappeler qu'il s'agit d'une requête de type "Union".
Exemple 2. Les champs mis en correspondance n'ont pas besoin de porter le
même nom, comme le montre l'exemple suivant, dans lequel nous avons modifié
les intitulés des champs de la table "Table2" :
nom
prénom
Chose
Jules
Machin
Pierre
Truc
Patrick
union
last-name
first-name
Pouf
Jean
Chose
Jules
=
nom
prénom
Chose
Jules
Machin
Pierre
Pouf
Jean
Truc
Patrick
Table1
Table2
Résultat
La requête union correspondante est représentée ci-dessous. Le SGBD sait que
"last-name" correspond à "nom", et "first-name" à "prénom", parce que les champs
sont cités dans cet ordre dans les deux clauses SELECT. La feuille de données
résultante emprunte les noms de ses champs à la première table. La présence
des crochets traduit le fait que SQL ne tolère pas le tiret dans les noms des tables
ni dans ceux des champs (caractère non autorisé).
SELECT nom, prénom
FROM Table1
UNION
SELECT [last-name], [first-name]
FROM Table2;
Exemple 3. Nous pouvons faire en sorte d'imposer les noms des champs dans la
feuille de données résultante pour obtenir, par exemple, le résultat suivant :
nom
prénom
Chose
Jules
Machin
Pierre
Truc
Patrick
union
nom
prénom
Pouf
Jean
Chose
Jules
=
Col1
Col2
Chose
Jules
Machin
Pierre
Pouf
Jean
Truc
Patrick
Table1
Table2
Résultat
En SQL, la requête s'écrit ainsi :
SELECT nom AS Col1, prénom AS Col2
FROM Table1
UNION
SELECT nom AS Col1, prénom AS Col2
FROM Table2;
Exemple 4. Nous pouvons appliquer des critères de sélection (clause WHERE)
aux enregistrements de chacune des deux tables que nous voulons réunir. Il faut
cependant que nous fassions bien attention à bien définir le même critère dans les
deux clauses SELECT. Ainsi, pour exclure les noms commençant par A, B ou C
dans le résultat final :
nom
prénom
Chose
Jules
Machin
Pierre
Truc
Patrick
union
nom
prénom
Pouf
Jean
Chose
Jules
=
nom
prénom
Machin
Pierre
Pouf
Jean
Truc
Patrick
Table1
Table2
Résultat (avec critères)
nous utilisons la requête union suivante :
SELECT nom, prénom
FROM Table1
WHERE nom>"D"
UNION
SELECT nom, prénom
FROM Table2
WHERE nom>"D";
Exemple 5. Pour faire en sorte que la requête union n'élimine pas les doublons,
nous rajoutons l'opérateur ALL après UNION, comme le montre la requête ci-
dessous :
SELECT nom, prénom
FROM Table1
UNION ALL
SELECT nom, prénom
FROM Table2;
La feuille de données obtenue résulte de la simple mise bout à bout des deux
tables, sans tri ni élimination des doublons :
nom
prénom
Chose
Jules
Machin
Pierre
Truc
Patrick
union all
nom
prénom
Pouf
Jean
Chose
Jules
=
Col1
Col2
Chose
Jules
Machin
Pierre
Truc
Patrick
Pouf
Jean
Chose
Jules
Table1
Table2
Résultat
Exemple 6. Comment faire en sorte que la requête Union crée une table ? Une
des techniques possibles consiste à emboîter la requête union dans une
commande d'insertion. Le code SQL suivant :
INSERT INTO Table3
SELECT *
FROM (SELECT nom, prénom
FROM Table1
UNION SELECT [last-name], [first-name]
FROM Table2);
peut être exécuté à condition que la table "Table3" ait été préalablement créée
(vide) -- mais cette condition n'est pas requise pour observer le résultat de la
requête en mode feuille de données. La requête ci-dessus est reconnue par le
SGBD Access comme une requête "Ajout" cause de la clause INSERT) et, si
nous l'enregistrons, son nom apparaît précéde l'icône correspondante. Le
code ci-dessus nous offre un exemple d'emboîtement en SQL.
Cet aspect didactique mis à part, il est plus simple, quand on opère dans le SGBD
Access, de réaliser d'abord la requête union, puis de réutiliser son résultat dans
une requête de sélection simple, à laquelle on demande de créer une table.
Remarque. Si nous tentons de réaliser l'union de deux tables contenant un champ
(nommé "essai") de type Mémo, Objet OLE ou Lien hypertexte, nous obtenons le
message suivant (rédigé dans le jargon franglais des informaticiens) :
Cela signifie que, dans le SGBD Access, la requête Union ne fonctionne pas sur
les champs de type Mémo, Objet OLE et Lien hypertexte. Pour réunir deux tables
comportant des champs de ce type sans les perdre, il faut utiliser la requête Ajout.
La requête Union présente un autre défaut : elle est lente à l'exécution, aussi bien
programmée soit-elle. Cela provient du fait qu'elle trie et dédoublonne, alors que la
requête Ajout se contente de compléter une table avec les données d'une autre. A
titre d'exemple, sur un PC de qualité standard, il faut environ plusieurs minutes (3-
4) pour réaliser l'union de 10.000 enregistrements avec 300.000 autres.
3 - L'intersection de deux tables
L'intersection de deux tables est une une feuille de données (ou une table)
contenant seulement les lignes communes aux deux tables. Les conditions sont
les mêmes que pour l'union. La figure ci-dessous illustre l'opération intersection :
nom
prénom
Chose
Jules
Machin
Pierre
Truc
Patrick
inter
nom
prénom
Pouf
Jean
Chose
Jules
=
nom
prénom
Chose
Jules
Le code SQL correspondant dépend de la version utilisée. En SQL1, il s'écrit :
SELECT nom, prénom
FROM Table1
WHERE Table1.nom IN (SELECT nom FROM Table2) AND Table1.prénom IN (SELECT prénom
FROM Table2);
Cette syntaxe, qui fait appel à l'emboîtement autant de fois qu'il y a de colonnes, a
été simplifiée par l'introduction de l'opérateur INTERSECT en SQL2. Le nouveau
code s'écrit :
SELECT nom, prénom
FROM Table1
INTERSECT
SELECT nom, prénom
FROM Table2;
Mais... le SGBD Access ne reconnaît pas l'opérateur INTERSECT. Il affiche un
message d'erreur qui, bien entendu, ne correspond pas à la situation (une
habitude bien ancrée en informatique). Seule reste en lice la première syntaxe, qui
apparaît de la manière suivante dans l'interface graphique :
Comme on peut le constater, il est possible d'utiliser des critères écrits en code
SQL dans l'interface graphique. Ma foi, autant utiliser la fenêtre SQL directement !
Que l'opérateur INTERSECT ne soit pas reconnu par Access n'est pas un drame.
Outre les deux commandes SQL déjà citées, nous en imaginer une troisième, qui
résulte directement de la définition de l'intersection :
SELECT DISTINCT Table1.nom, Table1.prénom
FROM Table1, Table2
WHERE Table1.nom=Table2.nom AND Table1.prénom=Table2.prénom;
La présence de l'opérateur DISTINCT est indispensable, sinon tous les
enregistrements de l'intersection figurent en double dans la feuille de données. Le
SGBD les écrit deux fois parce qu'il les trouve une fois dans la première table, et
une autre fois dans la seconde.
Le code ci-dessus est représenté ainsi dans l'interface graphique (on vérifie en
outre que la propriété "Valeurs distinctes" de la requête vaut "Oui") :
Nous pouvons encore traduire l'intersection en utilisant des relations (ou jointures)
entre les champs des deux tables. Rappelons qu'une relation créée dans la
fenêtre graphique de définition des requêtes possède une existence éphémère, ce
1 / 8 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !