sql >> Database >  >> RDS >> PostgreSQL

Query maken die id retourneert als voorwaarde overeenkomt in rijen uit twee tabellen

Heb uw vraag op Meta over deze specifieke vraag, laat me uitleggen waarom alle drie de antwoorden inderdaad correct zijn - net als de manier waarop je het hebt uitgewerkt.

Ik heb voorbeelden toegevoegd van alle drie de antwoorden en het schema waaraan ze werken:

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)

(stel van invoeginstructies)

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)

Een intersect gebruikt twee select-statements en levert overeenkomende resultaten op. In dit geval zoekt u naar alle rijen die een bijpassende kleur 'Lichtgeel' hebben.

Ik kan je geen voorbeeld geven in MySQL omdat het dit niet ondersteunt (zoals je hieronder kunt zien, is het niet nodig om dezelfde resultaten te geven).

Een samenvoegquery van twee select-statements, elk met een where-clausule die alleen de kleur 'Light Yellow' toestaat, levert dezelfde gegevens op. Hoewel een unie kan worden gebruikt om gegevens te retourneren die niet overeenkomen, betekent de where-clausule in elke select-instructie dat deze inderdaad alleen de gewenste rijen retourneert.

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, dat is slecht toch? Natuurlijk hebben we de waar-clausule niet gespecificeerd:

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)

Een join tussen twee tabellen op de kleur stelt u in staat om de rijen van beide tabellen in een enkele rij met gegevens te retourneren. U kunt de join op de twee tabellen specificeren voor de itemkleur en een where-component gebruiken om alleen de rijen te retourneren waarnaar u op zoek bent.

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)

Zoals u kunt zien, heeft dit alleen de rijen met een overeenkomende kleur geretourneerd en heeft u kolommen van beide tabellen in één rij van uw resultatenset kunnen plaatsen.

Ik heb dit duidelijk niet goed gepland, want ik heb geen andere overeenkomende resultaten behalve 'Lichtgeel' in beide tabellen, dus als ik er nog een paar invoer aan toevoeg, krijgen we dit:

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)

Nu kunnen we dat opnieuw uitvoeren, en deze keer krijgen:

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

Dit is nu waar we de join en de where-clausule samen gebruiken:

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)

Zie je, in SQL zijn er vaak meer manieren om hetzelfde resultaat op verschillende manieren te krijgen dan dat er variaties zijn van dezelfde gegevens in je tabellen.

Bewerken:Oké, dus als je alleen rijen wilt waar alles de gegevens komen overeen, neem het gewoon op in de syntaxis van de join:

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)

Zoals je kunt zien, vertellen we de join nu dat zowel de id en color velden moeten overeenkomen tussen de twee tabellen - en de resultaten spreken voor zich. Nu, in dit geval, ik nog steeds kwam niet overeen met ALLE kolommen omdat het materiaal anders is. Als u verder wilt zoeken, zou de zoekopdracht geen resultaten opleveren omdat ik geen overeenkomende records heb waarbij de id, het materiaal EN de kleur overeenkomen, maar de syntaxis zou als volgt zijn:

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)

Wat dat betreft wil je in de meeste gevallen niet alles de kolommen die overeenkomen. Heel vaak hebben tabellen een ID die alleen voor die tabel wordt gebruikt en een automatisch oplopende waarde is. U wilt het gebruiken om een ​​unieke rij te identificeren in die tabel, maar niet om het te gebruiken om niet-gerelateerde tabellen te matchen. Ik zou je hebben voorgesteld om te matchen op materiaal en kleur - maar laat de ID erbuiten.



  1. Hoe een afbeelding van SQL Server in de afbeeldingsbox te laden?

  2. PostgreSQL gecomprimeerde archieflogboeken in Windows

  3. Microseconden aftrekken van een Datetime-waarde in MariaDB

  4. MySQL Dubbele kolomfout alleen wanneer query ingepakt als subquery