PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Erstellen einer Abfrage, die eine ID zurückgibt, wenn die Bedingung in Zeilen aus zwei Tabellen übereinstimmt

Habe gelesen Ihre Frage auf Meta zu dieser speziellen Frage, lassen Sie mich erklären, warum alle drei Antworten tatsächlich richtig sind - ebenso wie Sie es ausgearbeitet haben.

Ich habe Beispiele für alle drei Antworten und das Schema, an dem sie arbeiten, beigefügt:

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)

(Haufen von Insert-Anweisungen)

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)

Ein Intersect verwendet zwei select-Anweisungen und bringt übereinstimmende Ergebnisse zurück. In diesem Fall suchen Sie nach allen Zeilen, die die übereinstimmende Farbe „Hellgelb“ haben.

Ich kann Ihnen kein Beispiel in MySQL geben, da es dies nicht unterstützt (wie Sie unten sehen können, ist es nicht erforderlich, um die gleichen Ergebnisse zu erzielen).

Eine Vereinigungsabfrage von zwei select-Anweisungen mit jeweils einer where-Klausel, die nur die Farbe „Hellgelb“ zulässt, gibt dieselben Daten zurück. Obwohl eine Union verwendet werden kann, um Daten zurückzugeben, die nicht übereinstimmen, bedeutet die where-Klausel in jeder select-Anweisung, dass tatsächlich nur die gewünschten Zeilen zurückgegeben werden.

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, das ist schlecht, oder? Natürlich haben wir die where-Klausel nicht angegeben:

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)

Ein Join zwischen zwei Tabellen für die Farbe ermöglicht es Ihnen, die Zeilen aus beiden Tabellen in einer einzigen Datenzeile zurückzugeben. Sie können den Join für die beiden Tabellen für die Elementfarbe angeben und eine where-Klausel verwenden, um nur die Zeilen zurückzugeben, nach denen Sie suchen.

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)

Wie Sie sehen können, hat dies nur die Zeilen mit einer übereinstimmenden Farbe zurückgegeben und es Ihnen ermöglicht, Spalten aus beiden Tabellen in einer einzigen Zeile Ihrer Ergebnismenge zu haben.

Nun, ich habe das offensichtlich nicht sehr gut geplant, da ich außer „Hellgelb“ in beiden Tabellen keine anderen übereinstimmenden Ergebnisse habe. Wenn ich also ein paar weitere Einträge hinzufüge, erhalten wir Folgendes:

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)

Jetzt können wir das noch einmal ausführen und erhalten diesmal:

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 nein!

Hier verwenden wir jetzt die Join- und die Where-Klausel zusammen:

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)

Sie sehen, in SQL gibt es oft mehr Möglichkeiten, dasselbe Ergebnis auf unterschiedliche Weise zu erhalten, als Variationen derselben Daten in Ihren Tabellen.

Bearbeiten:Okay, wenn Sie also nur Zeilen wollen, in denen alle die Daten übereinstimmen, fügen Sie sie einfach in die Join-Syntax ein:

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)

Wie Sie sehen können, teilen wir dem Join nun mit, dass sowohl die id und color Felder müssen zwischen den beiden Tabellen übereinstimmen - und die Ergebnisse sprechen für sich. Nun, in diesem Fall bin ich technisch gesehen immer noch stimmte nicht mit ALLEN Spalten überein, da das Material unterschiedlich ist. Wenn Sie weiter abgleichen wollten, würde die Abfrage keine Ergebnisse zurückgeben, da ich keine übereinstimmenden Datensätze habe, bei denen die ID, das Material UND die Farbe übereinstimmen, aber die Syntax wäre wie folgt:

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)

In diesem Sinne möchten Sie jedoch in den meisten Fällen nicht alle die passenden Spalten. Sehr oft haben Tabellen eine ID, die nur für diese Tabelle verwendet wird und ein automatisch inkrementierender Wert ist. Sie möchten es verwenden, um eine eindeutige Zeile darin das zu identifizieren Tabelle, aber nicht, um sie zum Abgleichen nicht verwandter Tabellen zu verwenden. Wenn überhaupt, hätte ich vorgeschlagen, dass Sie Material und Farbe abgleichen - aber die ID weglassen.