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

Création d'une requête qui renvoie l'identifiant si la condition correspond aux lignes de deux tables

Avoir lu votre question sur Meta à propos de cette question particulière, laissez-moi vous expliquer pourquoi les trois réponses sont en effet correctes - comme c'est la façon dont vous l'avez résolu.

J'ai inclus des exemples des trois réponses et du schéma sur lequel ils travaillent :

Database changed
mysql> create table carpet(id int(3), material varchar(10), color varchar(15));
Query OK, 0 rows affected (0.02 sec)

mysql> create table curtain(id int(3), material varchar(10), color varchar(15));
Query OK, 0 rows affected (0.00 sec)

(groupe d'instructions d'insertion)

mysql> select * from carpet;
+------+-----------+--------------+
| id   | material  | color        |
+------+-----------+--------------+
|    1 | wool      | Light Yellow |
|    2 | wool      | Beige        |
|    3 | polyester | Light Yellow |
|    4 | polyester | Light Red    |
+------+-----------+--------------+
4 rows in set (0.00 sec)

mysql> select * from curtain;
+------+----------+--------------+
| id   | material | color        |
+------+----------+--------------+
|    1 | Velvet   | Purple       |
|    2 | cotton   | White        |
|    3 | cotton   | Light Yellow |
|    4 | cotton   | Light Blue   |
+------+----------+--------------+
4 rows in set (0.00 sec)

Une intersection utilise deux instructions select et renvoie des résultats correspondants. Dans ce cas, vous recherchez toutes les lignes dont la couleur correspondante est 'Jaune clair'.

Je ne peux pas vous donner d'exemple dans MySQL car il ne le supporte pas (comme vous pouvez le voir ci-dessous, il n'est pas nécessaire de donner les mêmes résultats).

Une requête d'union de deux instructions select chacune avec une clause where n'autorisant que la couleur 'Light Yellow' renverra les mêmes données. Bien qu'une union puisse être utilisée pour renvoyer des données qui ne correspondent pas, la clause where de chaque instruction select signifie qu'elle renverra uniquement les lignes souhaitées.

mysql> select id, material, color from carpet
    -> union 
    -> select id, material, color from curtain;
+------+-----------+--------------+
| id   | material  | color        |
+------+-----------+--------------+
|    1 | wool      | Light Yellow |
|    2 | wool      | Beige        |
|    3 | polyester | Light Yellow |
|    4 | polyester | Light Red    |
|    1 | Velvet    | Purple       |
|    2 | cotton    | White        |
|    3 | cotton    | Light Yellow |
|    4 | cotton    | Light Blue   |
+------+-----------+--------------+
8 rows in set (0.00 sec)

Aww, c'est mauvais non? Bien sûr, nous n'avons pas spécifié la clause where :

mysql> select id, material, color from carpet where color='Light Yellow'
    -> union
    -> select id, material, color from curtain where color='Light Yellow';
+------+-----------+--------------+
| id   | material  | color        |
+------+-----------+--------------+
|    1 | wool      | Light Yellow |
|    3 | polyester | Light Yellow |
|    3 | cotton    | Light Yellow |
+------+-----------+--------------+
3 rows in set (0.00 sec)

Une jointure entre deux tables sur la couleur vous permettra de renvoyer les lignes des deux tables dans une seule ligne de données. Vous pouvez spécifier la jointure sur les deux tables pour la couleur de l'élément et utiliser une clause where pour renvoyer uniquement les lignes que vous recherchez.

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a join carpet b on a.color=b.color;
+------+----------+--------------+------+-----------+
| id   | material | color        | id   | material  |
+------+----------+--------------+------+-----------+
|    3 | cotton   | Light Yellow |    1 | wool      |
|    3 | cotton   | Light Yellow |    3 | polyester |
+------+----------+--------------+------+-----------+
2 rows in set (0.00 sec)

Comme vous pouvez le voir, cela n'a renvoyé que les lignes avec une couleur correspondante et vous a permis d'avoir des colonnes des deux tables dans une seule ligne de votre jeu de résultats.

Maintenant, je n'ai clairement pas très bien planifié cela car je n'ai pas d'autres résultats correspondants à part le "jaune clair" dans les deux tableaux, donc si j'ajoute quelques entrées supplémentaires, nous obtenons ceci :

mysql> select * from curtain;
+------+----------+--------------+
| id   | material | color        |
+------+----------+--------------+
|    1 | Velvet   | Purple       |
|    2 | cotton   | White        |
|    3 | cotton   | Light Yellow |
|    4 | cotton   | Light Blue   |
|    5 | Wool     | White        |
|    6 | Fluff    | Beige        |
+------+----------+--------------+
6 rows in set (0.00 sec)

mysql> select * from carpet;
+------+-----------+--------------+
| id   | material  | color        |
+------+-----------+--------------+
|    1 | wool      | Light Yellow |
|    2 | wool      | Beige        |
|    3 | polyester | Light Yellow |
|    4 | polyester | Light Red    |
|    5 | Fluff     | Light Blue   |
+------+-----------+--------------+
5 rows in set (0.00 sec)

Maintenant, nous pouvons exécuter cela à nouveau, et cette fois obtenir :

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a join carpet b on a.color=b.color;
+------+----------+--------------+------+-----------+
| id   | material | color        | id   | material  |
+------+----------+--------------+------+-----------+
|    3 | cotton   | Light Yellow |    1 | wool      |
|    3 | cotton   | Light Yellow |    3 | polyester |
|    4 | cotton   | Light Blue   |    5 | Fluff     |
|    6 | Fluff    | Beige        |    2 | wool      |
+------+----------+--------------+------+-----------+
4 rows in set (0.00 sec)

Oh non !

C'est ici que nous utilisons ensemble la jointure et la clause where :

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a join carpet b on a.color=b.color 
    -> where a.color='Light Yellow';
+------+----------+--------------+------+-----------+
| id   | material | color        | id   | material  |
+------+----------+--------------+------+-----------+
|    3 | cotton   | Light Yellow |    1 | wool      |
|    3 | cotton   | Light Yellow |    3 | polyester |
+------+----------+--------------+------+-----------+
2 rows in set (0.00 sec)

Vous voyez, en SQL, il y a souvent plus de façons d'obtenir le même résultat par différents moyens qu'il n'y a de variations des mêmes données dans vos tables.

Edit :Ok, donc si vous ne voulez que des lignes où tous les données correspondent, incluez-les simplement dans la syntaxe de jointure :

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a 
    -> join carpet b on a.color=b.color
    -> and a.id=b.id
    -> where a.color='Light Yellow';
+------+----------+--------------+------+-----------+
| id   | material | color        | id   | material  |
+------+----------+--------------+------+-----------+
|    3 | cotton   | Light Yellow |    3 | polyester |
+------+----------+--------------+------+-----------+
1 row in set (0.00 sec)

Comme vous pouvez le voir, nous disons maintenant à la jointure que le id et color les champs doivent correspondre entre les deux tables - et les résultats parlent d'eux-mêmes. Maintenant, dans ce cas, techniquement, j'encore ne correspondait pas à TOUTES les colonnes car le matériau est différent. Si vous vouliez faire correspondre davantage, la requête ne renverrait aucun résultat car je n'ai aucun enregistrement correspondant où l'identifiant, le matériau ET la couleur correspondent, mais la syntaxe serait la suivante :

mysql> select a.id, a.material, a.color, b.id, b.material 
    -> from curtain a 
    -> join carpet b on a.color=b.color
    -> and a.id=b.id
    -> and a.material=b.material
    -> where a.color='Light Yellow';
Empty set (0.00 sec)

Sur cette note cependant, dans la plupart des cas, vous ne voulez pas tout les colonnes à faire correspondre. Très souvent, les tables ont un ID qui n'est utilisé que pour cette table et qui est une valeur qui s'incrémente automatiquement. Vous souhaitez l'utiliser pour identifier une ligne unique dans qui table, mais pas pour l'utiliser pour faire correspondre des tables non liées. Si quoi que ce soit, j'aurais suggéré que vous correspondiez au matériau et à la couleur - mais laissez l'ID en dehors.