Mysql
 sql >> Base de données >  >> RDS >> Mysql

La requête SQL renvoie des données de plusieurs tables

Partie 1 – Jointures et unions

Cette réponse couvre :

  1. Partie 1
  2. Partie 2
    • Sous-requêtes :de quoi s'agit-il, où les utiliser et à quoi faire attention
    • Cartesian rejoint AKA - Oh, la misère !

Il existe plusieurs façons de récupérer des données à partir de plusieurs tables dans une base de données. Dans cette réponse, j'utiliserai 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é à 89, cela peut sembler beaucoup moins intuitif - mais tout ce que je peux dire, c'est de l'essayer) tel qu'il est beaucoup plus facile à comprendre lorsque les requêtes deviennent plus complexes. Pourquoi l'utiliser ? Y a-t-il un gain de performances ? La réponse courte c'est non, mais c'est c'est plus facile à lire une fois qu'on s'y est habitué. Il est plus facile de lire les requêtes écrites par d'autres personnes utilisant cette syntaxe.

Je vais également utiliser le concept d'un petit garage qui dispose d'une base de données pour suivre les voitures dont il dispose. Le propriétaire vous a embauché comme informaticien et s'attend à ce que vous puissiez lui fournir les données qu'il demande en un rien de temps.

J'ai créé un certain nombre de tables de recherche 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 un exemple de base de données qui a la structure suivante. Je vais essayer de penser aux erreurs courantes qui sont commises au début et d'expliquer ce qui ne va pas avec elles - ainsi que bien sûr de montrer 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 le caryard pourrait é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 relie tout. 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 fournira également suffisamment de données pour les rendre utiles.

Donc, pour entrer dans le vif du sujet, le patron veut connaître les identifiants de toutes les voitures de sport qu'il possède .

Il s'agit d'une simple jointure de deux tables. Nous avons un tableau qui identifie le modèle et le tableau avec le stock disponible. Comme vous pouvez le voir, les données du model colonne des cars table concerne les models colonne des cars table 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

Donc, cette requête semble bonne, n'est-ce pas ? Nous avons identifié les deux tables et contenant les informations dont nous avons besoin et 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 a en effet les bonnes colonnes, mais certaines d'entre elles existent dans les deux tables, de sorte que la base de données est confuse quant à la colonne réelle que nous entendons et où. Il existe deux solutions pour résoudre ce problème. Le premier est sympa et simple, nous pouvons utiliser tableName.columnName pour indiquer exactement à la base de données 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é et s'appelle l'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 vieillirait probablement rapidement, donc un moyen simple est de surnommer 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 comme cela a été demandé. Comme je préfère la méthode des alias de table plutôt que d'utiliser les noms de table encore et encore, je m'y tiendrai à partir de maintenant.

De toute évidence, nous devons ajouter une clause where à notre requête. Nous pouvons identifier les voitures de sport soit par ID=1 ou model='Sports' . Comme l'ID est indexé et la clé primaire (et il se trouve qu'il y a moins de saisie), utilisons-le 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, étant un patron et n'étant jamais satisfait de ce qu'il a demandé, il regarde les informations, puis dit Je veux aussi les couleurs .

D'accord, nous avons donc une bonne partie de notre requête déjà écrite, mais nous devons utiliser une troisième table qui est les couleurs. Maintenant, notre table d'informations principale cars stocke l'ID de couleur de la voiture et renvoie à la colonne d'ID de couleurs. Ainsi, de 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)

Merde, bien que le tableau ait été correctement joint et que les colonnes associées aient été liées, nous avons oublié d'extraire les informations réelles 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)

Bon, c'est le patron sur notre dos pour un moment. Maintenant, pour expliquer une partie de cela un peu plus en détail. Comme vous pouvez le voir, le from la clause dans notre déclaration lie notre table principale (j'utilise souvent une table qui contient des informations plutôt qu'une table de recherche ou de dimension. La requête fonctionnerait aussi bien avec les tables toutes inversées, mais aurait moins de sens lorsque nous revenons à cette requête pour le 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 une belle indentation pour que tout soit aussi clair que possible. continuez à enseigner aux autres, essayez d'instiller ces caractéristiques dans leurs requêtes - surtout si vous les dépannez.

Il est tout à fait possible de continuer à lier 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

Alors que j'ai oublié d'inclure une table où nous pourrions vouloir joindre plus d'une colonne dans le join déclaration, voici un exemple. Si les models la table avait des modèles spécifiques à la marque et avait donc également une colonne appelée brand qui renvoyaient aux brands tableau sur l'ID champ, cela pourrait être fait 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
            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 aux principales cars table, mais spécifie également les jointures entre les tables déjà jointes. Si cela n'a pas été fait, le résultat s'appelle une jointure cartésienne - ce qui est dba parler pour le mal. Une jointure cartésienne est une jointure dans laquelle les lignes sont renvoyées car les informations n'indiquent pas à la base de données comment limiter les résultats, de sorte que la requête renvoie tous les lignes qui correspondent aux critères.

Donc, 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 était demandé. Dans la requête, nous avons demandé l'ID de cars et le model à partir de models . Cependant, comme nous n'avons pas précisé comment pour joindre les tables, la base de données a trouvé chaque ligne du premier tableau avec chaque ligne du second tableau.

D'accord, donc le patron est de retour, et il veut encore plus d'informations. Je veux la même liste, mais y inclure également les 4x4 .

Cela nous donne cependant 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 ce qui précède fonctionne parfaitement bien, regardons-le différemment, c'est une excellente excuse pour montrer comment un union requête fonctionnera.

Nous savons que les éléments suivants renverront 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 ce qui suit renverrait 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

Donc en ajoutant un union all clause entre eux, les résultats de la deuxième requête seront ajoutés aux résultats de la première requête.

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 voir, les résultats de la première requête sont renvoyés en premier, suivis des résultats de la seconde 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 utiles pour des cas spécifiques. Ils sont un excellent moyen de renvoyer des résultats spécifiques à partir de tableaux à partir de tableaux qui ne sont pas facilement reliés entre eux - ou d'ailleurs complètement tableaux non liés. Il y a cependant quelques règles à suivre.

  • Les types de colonne de la première requête doivent correspondre aux types de colonne de toutes les autres requêtes ci-dessous.
  • 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 vous demander ce le la différence est entre l'utilisation de union et union all . Un union la requête supprimera les doublons, tandis qu'une union all Ne fera pas. Cela signifie qu'il y a un petit impact sur les performances lors de l'utilisation de union sur union all mais les résultats en valent peut-être la peine - je ne spéculerai pas sur ce genre de choses.

Sur cette note, il pourrait être utile de noter quelques notes supplémentaires ici.

  • Si nous voulions ordonner les résultats, nous pouvons utiliser un order by mais vous ne pouvez plus utiliser l'alias. Dans la requête ci-dessus, ajouter un order by a.ID entraînerait une erreur - en ce qui concerne les résultats, la colonne s'appelle 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 instruction, et elle doit être la dernière instruction.

Pour les exemples suivants, j'ajoute quelques lignes supplémentaires à nos tableaux.

J'ai ajouté Holden au tableau des marques. J'ai également ajouté une ligne dans cars qui a la color valeur de 12 - qui n'a aucune référence dans la table des couleurs.

D'accord, le patron est de retour, aboyant des demandes - * Je veux un décompte de chaque marque que nous vendons et le nombre de voitures qu'elle contient ! - Typiquement, nous arrivons juste à une section intéressante de notre discussion et le patron veut plus de travail .

D'accord, donc la première chose que nous devons 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 ceci à notre table de 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 la charmante Holden marque que j'ai ajoutée.

En effet, une jointure recherche les lignes correspondantes dans les deux les tables. Comme il n'y a pas de données dans les voitures de type Holden il n'est pas retourné. C'est là que nous pouvons utiliser un outer rejoindre. Cela renverra tous les résultats d'une table, qu'ils correspondent ou non à 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 avons cela, nous pouvons ajouter une belle fonction d'agrégation pour obtenir un décompte et nous débarrasser du patron pendant 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'éloigne.

Maintenant, pour expliquer cela plus en détail, les jointures externes peuvent être de la left ou right taper. La gauche ou la droite définit quelle table est entièrement inclus. Une left outer join inclura toutes les lignes de la table de gauche, tandis que (vous l'aurez deviné) une right outer join apporte tous les résultats du tableau de droite dans les résultats.

Certaines bases de données autoriseront une full outer join qui ramènera les résultats (qu'ils correspondent ou non) de les deux tables, mais cela n'est pas pris en charge dans toutes les bases de données.

Maintenant, je pense probablement qu'à ce stade, vous vous demandez si vous pouvez ou non fusionner les types de jointure dans une requête - et la réponse est oui, vous le pouvez 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'était pas 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 fonctionnerait pour obtenir les résultats que nous attendions :

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 voir, nous avons deux jointures externes dans la requête et les résultats arrivent comme prévu.

Maintenant, qu'en est-il de ces autres types de jointures que vous demandez ? Qu'en est-il des Intersections ?

Eh bien, toutes les bases de données ne prennent pas en charge l'intersect mais pratiquement toutes les bases de données vous permettront de créer une intersection via une jointure (ou au moins une instruction where bien structurée).

Une intersection est un type de jointure quelque peu similaire à une union comme décrit ci-dessus - mais la différence est qu'il seulement renvoie des lignes de données identiques (et je veux dire identiques) entre les différentes requêtes individuelles jointes par l'union. Seules les lignes identiques à tous égards seront renvoyées.

Un exemple simple serait comme tel :

select
    *
from
    colors
where
    ID>2
intersect
select
    *
from
    colors
where
    id<4

Alors qu'un union normal la requête renverrait toutes les lignes de la table (la première requête renvoyant quoi que ce soit sur ID>2 et le second n'importe quoi ayant ID<4 ) qui donnerait un ensemble complet, une requête d'intersection 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 une intersect requête, ce qui précède peut être facilement réalisé avec 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 effectuer une intersection sur 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 tableaux.