Partie 1 - Joints et unions
Cette réponse couvre :
- Partie 1
- La jointure de deux ou plusieurs tables à l'aide d'une jointure interne (voir la rubrique entrée de wikipédia pour plus d'informations)
- Comment utiliser une requête d'union
- Joints externes gauche et droit (cette réponse de stackOverflow est excellent pour décrire les types de jointures)
- Requêtes d'intersection (et comment les reproduire si votre base de données ne les supporte pas) - il s'agit d'une fonction de SQL-Server ( voir info ) et une partie de la la raison pour laquelle j'ai écrit tout ça en premier lieu.
- Partie 2
- Sous-requêtes - ce qu'elles sont, où elles peuvent être utilisées et ce dont il faut se méfier
- Cartesian joins AKA - Oh, la misère !
Il existe plusieurs façons d'extraire des données de plusieurs tables dans une base de données. Dans cette réponse, je vais utiliser la syntaxe de jointure ANSI-92. Cela peut être différent d'un certain nombre d'autres tutoriels qui utilisent l'ancienne syntaxe ANSI-89 (et si vous êtes habitué à la syntaxe 89, cela peut sembler beaucoup moins intuitif - mais tout ce que je peux dire, c'est d'essayer) car elle est beaucoup plus facile à comprendre lorsque les requêtes commencent à devenir plus complexes. Pourquoi l'utiliser ? Y a-t-il un gain de performance ? Le site réponse courte est non, mais il est plus facile à lire une fois qu'on s'y est habitué. Il est plus facile de lire des requêtes écrites par d'autres personnes utilisant cette syntaxe.
Je vais également utiliser le concept d'une petite cariole qui dispose d'une base de données pour suivre les voitures disponibles. Le propriétaire vous a engagé comme informaticien et s'attend à ce que vous soyez capable de lui fournir les données qu'il demande en un clin d'œil.
J'ai créé un certain nombre de tables de consultation qui seront utilisées par la table finale. Cela nous donnera un modèle raisonnable à partir duquel travailler. Pour commencer, je vais exécuter mes requêtes sur une base de données d'exemple qui a la structure suivante. J'essaierai de penser aux erreurs courantes que l'on commet lorsqu'on débute et j'expliquerai ce qui ne va pas avec elles - tout en montrant bien sûr comment les corriger.
Le premier tableau est simplement une liste de couleurs afin que nous sachions quelles couleurs nous avons dans le parc automobile.
mysql> create table colors(id int(3) not null auto_increment primary key,
-> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | varchar(15) | YES | | NULL | |
| paint | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> insert into colors (color, paint) values ('Red', 'Metallic'),
-> ('Green', 'Gloss'), ('Blue', 'Metallic'),
-> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from colors;
+----+-------+----------+
| id | color | paint |
+----+-------+----------+
| 1 | Red | Metallic |
| 2 | Green | Gloss |
| 3 | Blue | Metallic |
| 4 | White | Gloss |
| 5 | Black | Gloss |
+----+-------+----------+
5 rows in set (0.00 sec)
Le tableau des marques identifie les différentes marques de voitures que les caryards pourraient éventuellement vendre.
mysql> create table brands (id int(3) not null auto_increment primary key,
-> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| brand | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
mysql> insert into brands (brand) values ('Ford'), ('Toyota'),
-> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from brands;
+----+--------+
| id | brand |
+----+--------+
| 1 | Ford |
| 2 | Toyota |
| 3 | Nissan |
| 4 | Smart |
| 5 | BMW |
+----+--------+
5 rows in set (0.00 sec)
Le tableau des modèles couvrira différents types de voitures, il sera plus simple pour cela d'utiliser différents types de voitures plutôt que des modèles de voitures réels.
mysql> create table models (id int(3) not null auto_increment primary key,
-> model varchar(15));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| model | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from models;
+----+--------+
| id | model |
+----+--------+
| 1 | Sports |
| 2 | Sedan |
| 3 | 4WD |
| 4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)
Et enfin, pour lier toutes ces autres tables, la table qui lie tout ensemble. Le champ ID est en fait le numéro de lot unique utilisé pour identifier les voitures.
mysql> create table cars (id int(3) not null auto_increment primary key,
-> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)
mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| color | int(3) | YES | | NULL | |
| brand | int(3) | YES | | NULL | |
| model | int(3) | YES | | NULL | |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1),
-> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
| 1 | 1 | 2 | 1 |
| 2 | 3 | 1 | 2 |
| 3 | 5 | 3 | 1 |
| 4 | 4 | 4 | 2 |
| 5 | 2 | 2 | 3 |
| 6 | 3 | 5 | 4 |
| 7 | 4 | 1 | 3 |
| 8 | 2 | 2 | 1 |
| 9 | 5 | 2 | 3 |
| 10 | 4 | 5 | 1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)
Cela nous donnera suffisamment de données (je l'espère) pour couvrir les exemples ci-dessous de différents types de jointures et aussi suffisamment de données pour les rendre utiles.
Donc, en entrant dans le vif du sujet, le patron veut savoir Les numéros d'identification de toutes les voitures de sport qu'il possède. .
Il s'agit d'une simple jointure de deux tables. Nous avons une table qui identifie le modèle et une table qui contient le stock disponible. Comme vous pouvez le voir, les données dans la table model
de la colonne cars
se rapporte à la models
de la colonne cars
que nous avons. Maintenant, nous savons que la table des modèles a un ID de 1
pour Sports
alors écrivons la jointure.
select
ID,
model
from
cars
join models
on model=ID
Cette requête semble bonne, non ? Nous avons identifié les deux tables qui contiennent les informations dont nous avons besoin et nous utilisons une jointure qui identifie correctement les colonnes à joindre.
ERROR 1052 (23000): Column 'ID' in field list is ambiguous
Oh non ! Une erreur dans notre première requête ! Oui, et c'est une prune. Vous voyez, la requête contient bien les bonnes colonnes, mais certaines d'entre elles existent dans les deux tables, si bien que la base de données ne sait plus de quelle colonne il s'agit et où. Il y a deux solutions pour résoudre ce problème. La première est très simple, nous pouvons utiliser tableName.columnName
pour dire à la base de données exactement ce que nous voulons dire, comme ceci :
select
cars.ID,
models.model
from
cars
join models
on cars.model=models.ID
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
| 2 | Sedan |
| 4 | Sedan |
| 5 | 4WD |
| 7 | 4WD |
| 9 | 4WD |
| 6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)
L'autre est probablement plus souvent utilisée et est appelée aliasing de table. Les tables de cet exemple ont des noms simples et courts, mais en tapant quelque chose comme KPI_DAILY_SALES_BY_DEPARTMENT
deviendrait rapidement obsolète. Une façon simple de procéder est de donner un surnom à la table comme ceci :
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
Maintenant, revenons à la demande. Comme vous pouvez le voir, nous avons les informations dont nous avons besoin, mais nous avons également des informations qui n'ont pas été demandées, nous devons donc inclure une clause where dans la déclaration pour obtenir uniquement les voitures de sport demandées. Comme je préfère la méthode des alias de table à l'utilisation répétée des noms de table, je vais m'y tenir à partir de maintenant.
Il est clair que nous devons ajouter une clause where à notre requête. Nous pouvons identifier les voitures de sport soit par ID=1
o model='Sports'
. Comme l'ID est indexé et qu'il s'agit de la clé primaire (et qu'il se trouve qu'elle est moins typée), utilisons-la dans notre requête.
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
Bingo ! Le patron est content. Bien sûr, comme il est un patron et qu'il n'est jamais satisfait de ce qu'il a demandé, il regarde les informations, puis dit Je veux aussi les couleurs .
Bon, nous avons donc déjà écrit une bonne partie de notre requête, mais nous devons utiliser une troisième table, celle des couleurs. Maintenant, notre table d'information principale cars
stocke l'ID de la couleur de la voiture, ce qui renvoie à la colonne ID des couleurs. Donc, d'une manière similaire à l'original, nous pouvons joindre une troisième table :
select
a.ID,
b.model
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 3 | Sports |
| 8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)
Bon sang, bien que la table ait été correctement jointe et que les colonnes liées aient été reliées, nous avons oublié de tirer dans le véritable information de la nouvelle table que nous venons de lier.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
where
b.ID=1
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
+----+--------+-------+
4 rows in set (0.00 sec)
Bien, le patron n'est plus sur notre dos pour un moment. Maintenant, pour expliquer un peu plus en détail. Comme vous pouvez le voir, le from
dans notre déclaration relie notre tableau principal (j'utilise souvent un tableau qui contient des informations plutôt qu'un tableau de consultation ou de dimension. La requête fonctionnerait tout aussi bien si les tables étaient interverties, mais elle aurait moins de sens si nous revenions à cette requête pour la lire dans quelques mois. Il est donc souvent préférable d'essayer d'écrire une requête qui sera agréable et facile à comprendre - présentez-la de manière intuitive, utilisez de belles indentations pour que tout soit aussi clair que possible. Si vous enseignez ensuite à d'autres personnes, essayez d'inculquer ces caractéristiques à leurs requêtes, surtout si vous devez les dépanner.
Il est tout à fait possible de relier de plus en plus de tables de cette manière.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
Bien que j'aie oublié d'inclure un tableau dans lequel nous pourrions vouloir joindre plus d'une colonne dans le fichier join
Voici un exemple. Si le models
avait des modèles spécifiques à une marque et avait donc aussi une colonne appelée brand
qui renvoie à la brands
table sur le ID
on pourrait procéder comme suit :
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
and b.brand=d.ID
where
b.ID=1
Vous pouvez voir que la requête ci-dessus ne relie pas seulement les tables jointes à la table principale. cars
mais spécifie également les jointures entre les tables déjà jointes. Si cela n'a pas été fait, le résultat est appelé jointure cartésienne - ce qui est le terme de dba pour mauvais. Une jointure cartésienne est une jointure où des lignes sont renvoyées parce que les informations ne disent pas à la base de données comment limiter les résultats, de sorte que la requête renvoie tous les lignes qui répondent aux critères.
Ainsi, pour donner un exemple de jointure cartésienne, exécutons la requête suivante :
select
a.ID,
b.model
from
cars a
join models b
+----+--------+
| ID | model |
+----+--------+
| 1 | Sports |
| 1 | Sedan |
| 1 | 4WD |
| 1 | Luxury |
| 2 | Sports |
| 2 | Sedan |
| 2 | 4WD |
| 2 | Luxury |
| 3 | Sports |
| 3 | Sedan |
| 3 | 4WD |
| 3 | Luxury |
| 4 | Sports |
| 4 | Sedan |
| 4 | 4WD |
| 4 | Luxury |
| 5 | Sports |
| 5 | Sedan |
| 5 | 4WD |
| 5 | Luxury |
| 6 | Sports |
| 6 | Sedan |
| 6 | 4WD |
| 6 | Luxury |
| 7 | Sports |
| 7 | Sedan |
| 7 | 4WD |
| 7 | Luxury |
| 8 | Sports |
| 8 | Sedan |
| 8 | 4WD |
| 8 | Luxury |
| 9 | Sports |
| 9 | Sedan |
| 9 | 4WD |
| 9 | Luxury |
| 10 | Sports |
| 10 | Sedan |
| 10 | 4WD |
| 10 | Luxury |
+----+--------+
40 rows in set (0.00 sec)
Bon dieu, c'est moche. Cependant, en ce qui concerne la base de données, c'est exactement ce qui a été demandé. Dans la requête, nous avons demandé pour le ID
de cars
y el model
de models
. Cependant, comme nous n'avons pas spécifié comment pour joindre les tables, la base de données a fait correspondre chaque de la première table avec chaque de la deuxième table.
Ok, donc le patron est de retour, et il veut encore plus d'informations. Je veux la même liste, mais en y incluant les 4x4. .
Cependant, cela nous donne une excellente excuse pour examiner deux façons différentes d'y parvenir. Nous pourrions ajouter une autre condition à la clause where comme ceci :
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
or b.ID=3
Bien que la méthode ci-dessus fonctionne parfaitement bien, regardons-la différemment, c'est une excellente excuse pour montrer comment une union
La requête fonctionnera.
Nous savons que les suivantes rendront toutes les voitures de sport :
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
Et les suivants rendraient tous les 4x4 :
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
Ainsi, en ajoutant un union all
entre elles, les résultats de la seconde requête seront ajoutés aux résultats de la première.
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=1
union all
select
a.ID,
b.model,
c.color
from
cars a
join models b
on a.model=b.ID
join colors c
on a.color=c.ID
join brands d
on a.brand=d.ID
where
b.ID=3
+----+--------+-------+
| ID | model | color |
+----+--------+-------+
| 1 | Sports | Red |
| 8 | Sports | Green |
| 10 | Sports | White |
| 3 | Sports | Black |
| 5 | 4WD | Green |
| 7 | 4WD | White |
| 9 | 4WD | Black |
+----+--------+-------+
7 rows in set (0.00 sec)
Comme vous pouvez le constater, les résultats de la première requête sont renvoyés en premier, suivis des résultats de la deuxième requête.
Dans cet exemple, il aurait bien sûr été beaucoup plus facile d'utiliser simplement la première requête, mais union
Les requêtes peuvent être excellentes pour des cas spécifiques. Elles constituent un excellent moyen de renvoyer des résultats spécifiques à partir de tables qui ne sont pas facilement reliées entre elles - ou d'ailleurs complètement des tables sans rapport entre elles. Il y a cependant quelques règles à suivre.
- Les types de colonnes de la première requête doivent correspondre aux types de colonnes de toutes les autres requêtes suivantes.
- Les noms des colonnes de la première requête seront utilisés pour identifier l'ensemble des résultats.
- Le nombre de colonnes dans chaque requête doit être le même.
Maintenant, vous pourriez se demander ce que le La différence se situe entre l'utilisation union
y union all
. A union
supprimera les doublons, tandis que la requête union all
ne le fera pas. Cela signifie qu'il y a une légère baisse de performance lors de l'utilisation de l'application union
sur union all
mais les résultats peuvent en valoir la peine - je ne vais pas spéculer sur ce genre de choses dans le cadre de ce dossier.
Sur ce point, il pourrait être utile de noter quelques remarques supplémentaires ici.
- Si nous voulions ordonner les résultats, nous pouvons utiliser une fonction
order by
mais vous ne pouvez plus utiliser l'alias. Dans la requête ci-dessus, l'ajout d'un order by a.ID
entraînerait une erreur - en ce qui concerne les résultats, la colonne est appelée ID
plutôt que a.ID
- même si le même alias a été utilisé dans les deux requêtes.
- Nous ne pouvons avoir qu'un seul
order by
et il doit s'agir de la dernière déclaration.
Pour les prochains exemples, je vais ajouter quelques lignes supplémentaires à nos tableaux.
J'ai ajouté Holden
dans le tableau des marques. J'ai également ajouté une ligne dans cars
qui a le color
valeur de 12
- qui n'a pas de référence dans le tableau des couleurs.
Ok, le patron est de retour, aboyant des demandes - *Je veux un compte de chaque marque que nous portons et le nombre de voitures dans celle-ci!` - Typique, nous arrivons juste à une section intéressante de notre discussion et le patron veut plus de travail.
Rightyo, donc la première chose à faire est d'obtenir une liste complète des marques possibles.
select
a.brand
from
brands a
+--------+
| brand |
+--------+
| Ford |
| Toyota |
| Nissan |
| Smart |
| BMW |
| Holden |
+--------+
6 rows in set (0.00 sec)
Maintenant, lorsque nous joignons cette table à celle des voitures, nous obtenons le résultat suivant :
select
a.brand
from
brands a
join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Nissan |
| Smart |
| Toyota |
+--------+
5 rows in set (0.00 sec)
Ce qui est bien sûr un problème - nous ne voyons aucune mention de l'adorable Holden
marque que j'ai ajoutée.
C'est parce qu'une jointure cherche des lignes correspondantes dans ambos tables. Comme il n'y a pas de données dans les voitures qui soient de type Holden
il n'est pas renvoyé. C'est là que nous pouvons utiliser un outer
rejoindre. Cela donnera tous les résultats d'une table, qu'ils correspondent ou non à ceux de l'autre table :
select
a.brand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+
| brand |
+--------+
| BMW |
| Ford |
| Holden |
| Nissan |
| Smart |
| Toyota |
+--------+
6 rows in set (0.00 sec)
Maintenant que nous l'avons, nous pouvons ajouter une belle fonction d'agrégation pour obtenir un compte et nous débarrasser du patron pour un moment.
select
a.brand,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
group by
a.brand
+--------+--------------+
| brand | countOfBrand |
+--------+--------------+
| BMW | 2 |
| Ford | 2 |
| Holden | 0 |
| Nissan | 1 |
| Smart | 1 |
| Toyota | 5 |
+--------+--------------+
6 rows in set (0.00 sec)
Et avec ça, le patron s'en va en se cachant.
Pour expliquer cela plus en détail, les jointures externes peuvent être de type left
o right
type. La gauche ou la droite définit quelle table est entièrement inclus. A left outer join
inclura toutes les lignes du tableau de gauche, tandis que (vous l'avez deviné) un fichier right outer join
apporte tous les résultats du tableau de droite dans les résultats.
Certaines bases de données permettent à un full outer join
qui ramènera les résultats (qu'ils soient appariés ou non) à partir de ambos mais cela n'est pas pris en charge par toutes les bases de données.
Je pense qu'à ce stade, vous vous demandez si vous pouvez ou non fusionner les types de jointures dans une requête, et la réponse est oui, absolument.
select
b.brand,
c.color,
count(a.id) as countOfBrand
from
cars a
right outer join brands b
on b.ID=a.brand
join colors c
on a.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| Ford | Blue | 1 |
| Ford | White | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| BMW | Blue | 1 |
| BMW | White | 1 |
+--------+-------+--------------+
9 rows in set (0.00 sec)
Alors, pourquoi n'est-ce pas les résultats escomptés ? C'est parce que, bien que nous ayons sélectionné la jointure externe des voitures aux marques, elle n'a pas été spécifiée dans la jointure aux couleurs - donc cette jointure particulière ne ramènera que les résultats qui correspondent dans les deux tables.
Voici la requête qui permettrait d'obtenir les résultats escomptés :
select
a.brand,
c.color,
count(b.id) as countOfBrand
from
brands a
left outer join cars b
on a.ID=b.brand
left outer join colors c
on b.color=c.ID
group by
a.brand,
c.color
+--------+-------+--------------+
| brand | color | countOfBrand |
+--------+-------+--------------+
| BMW | Blue | 1 |
| BMW | White | 1 |
| Ford | Blue | 1 |
| Ford | White | 1 |
| Holden | NULL | 0 |
| Nissan | Black | 1 |
| Smart | White | 1 |
| Toyota | NULL | 1 |
| Toyota | Black | 1 |
| Toyota | Green | 2 |
| Toyota | Red | 1 |
+--------+-------+--------------+
11 rows in set (0.00 sec)
Comme nous pouvons le constater, nous avons deux jointures externes dans la requête et les résultats sont conformes aux attentes.
Maintenant, qu'en est-il de ces autres types de jointures, vous vous demandez ? Qu'en est-il des Intersections ?
Toutes les bases de données ne supportent pas l'option intersection
mais pratiquement toutes les bases de données vous permettront de créer une intersection par le biais d'une jointure (ou au moins d'une instruction where bien structurée).
Une Intersection est un type de jointure similaire à une union
comme décrit ci-dessus - mais la différence est qu'elle sólo renvoie les lignes de données qui sont identiques (et je dis bien identiques) entre les différentes requêtes individuelles jointes par l'union. Seules les lignes qui sont identiques à tous égards seront retournées.
Un exemple simple serait le suivant :
select
*
from
colors
where
ID>2
intersect
select
*
from
colors
where
id<4
Alors qu'une union
renverrait toutes les lignes de la table (la première requête renvoyant quelque chose de plus que ID>2
et la seconde chose ayant ID<4
) qui donnerait un ensemble complet, une requête intersect ne renverrait que la ligne correspondant à id=3
car il répond aux deux critères.
Maintenant, si votre base de données ne prend pas en charge l'option intersect
La requête ci-dessus peut être facilement complétée par la requête suivante :
select
a.ID,
a.color,
a.paint
from
colors a
join colors b
on a.ID=b.ID
where
a.ID>2
and b.ID<4
+----+-------+----------+
| ID | color | paint |
+----+-------+----------+
| 3 | Blue | Metallic |
+----+-------+----------+
1 row in set (0.00 sec)
Si vous souhaitez réaliser une intersection entre deux tables différentes à l'aide d'une base de données qui ne prend pas en charge de manière inhérente une requête d'intersection, vous devrez créer une jointure sur chaque colonne des tables.