Opérateurs ensemblistes

Informations[1]

Objectifs

  • Comprendre l'analogie entre table et ensemble.

  • Savoir réaliser des opérations ensemblistes sur des tables.

Mise en situation

Imaginez que vous gériez une base de données qui liste tous les langages de programmation. Vous décidez d'effectuer votre découpage en tables, selon le type du langage : impératif, comme C, déclaratif, comme SQL, événementiel, comme JavaScript, etc. Vous obtenez donc une table par type de langage.

Mais certains langages ont plusieurs types ! Par exemple, JavaScript est à la fois impératif et événementiel.

Comment faire pour récupérer tous les langages qui sont à la fois impératifs et événementiels ? Cette opération est très facile si on utilise les opérateurs ensemblistes.

Introduction

On peut voir les tables comme des ensembles sur lesquels on peut réaliser des opérations ensemblistes. Pour ce faire, on utilise des opérateurs ensemblistes.

SyntaxeUnion

1
SELECT * FROM R1
2
UNION
3
SELECT * FROM R2

Exemple

1
CREATE TABLE parent (
2
id INTEGER PRIMARY KEY,
3
nom VARCHAR(255),
4
prenom VARCHAR(255), 
5
age INTEGER CHECK (age > 0)
6
);
7
8
INSERT INTO parent VALUES (1, 'Brasseur', 'Alexandre', 91);
9
INSERT INTO parent VALUES (2, 'Brasseur', 'Pierre', 67);
10
11
CREATE TABLE enfant (
12
id INTEGER PRIMARY KEY,
13
nom VARCHAR(255),
14
prenom VARCHAR(255), 
15
age INTEGER CHECK (age > 0)
16
);
17
18
INSERT INTO enfant VALUES (2, 'Brasseur', 'Pierre', 67);
19
INSERT INTO enfant VALUES (3, 'Brasseur', 'Claude', 42);
1
SELECT * 
2
FROM enfant
3
UNION 
4
SELECT *
5
FROM parent;
1
 id |   nom    |  prenom   | age 
2
----+----------+-----------+-----
3
  2 | Brasseur | Pierre    |  67
4
  3 | Brasseur | Claude    |  42
5
  1 | Brasseur | Alexandre |  91

RemarqueDédoublonnage

Par défaut UNION supprime les doublons, la clause UNION ALL permet de conserver les doublons.

Attention

Pour qu'un opérateur ensembliste soit valide il est nécessaire que les deux relations membres aient le même schéma.

Exemple

1
CREATE TABLE parent (
2
id INTEGER PRIMARY KEY,
3
nom VARCHAR(255),
4
prenom VARCHAR(255), 
5
age INTEGER CHECK (age > 0)
6
);
7
8
INSERT INTO parent VALUES (1, 'Brasseur', 'Alexandre', 91);
9
INSERT INTO parent VALUES (2, 'Brasseur', 'Pierre', 67);
10
11
CREATE TABLE enfant (
12
id INTEGER PRIMARY KEY,
13
nom VARCHAR(255),
14
prenom VARCHAR(255), 
15
age INTEGER CHECK (age > 0),
16
parent INTEGER NOT NULL,
17
FOREIGN KEY (parent) REFERENCES parent(id)
18
);
19
20
INSERT INTO enfant VALUES (2, 'Brasseur', 'Pierre', 67, 1);
21
INSERT INTO enfant VALUES (3, 'Brasseur', 'Claude', 42, 2);
1
/** Cette requête renvoie une erreur car les schémas ne sont pas identiques. */
2
SELECT * 
3
FROM enfant
4
UNION 
5
SELECT *
6
FROM parent;
1
/** Cette requête fonctionne car après la projection les schémas sont identiques. */
2
SELECT id, nom, prenom, age
3
FROM enfant
4
UNION 
5
SELECT id, nom, prenom, age
6
FROM parent;

SyntaxeIntersection

1
SELECT * FROM R1
2
INTERSECT
3
SELECT * FROM R2

Exemple

1
SELECT id, nom, prenom, age
2
FROM enfant
3
INTERSECT 
4
SELECT id, nom, prenom, age
5
FROM parent;
1
 id |   nom    | prenom | age 
2
----+----------+--------+-----
3
  2 | Brasseur | Pierre |  67

On sélectionne ici les personnes qui sont enfants et parents.

SyntaxeDifférence

1
SELECT * FROM R1
2
EXCEPT
3
SELECT * FROM R2

Exemple

1
SELECT id, nom, prenom, age
2
FROM enfant
3
EXCEPT 
4
SELECT id, nom, prenom, age
5
FROM parent;
1
 id |   nom    | prenom | age 
2
----+----------+--------+-----
3
  3 | Brasseur | Claude |  42

On sélectionne ici les enfants qui ne sont pas des parents.

Remarque

Les opérations INTERSECT et EXCEPT n'existent que dans la norme SQL2, et non dans la norme SQL1. Certains SGBD sont susceptibles de ne pas les implémenter.