sql >> Database teknologi >  >> RDS >> PostgreSQL

Oprettelse af forespørgsel, der returnerer id, hvis betingelse matches i rækker fra to tabeller

Har læst dit spørgsmål på Meta om netop dette spørgsmål, lad mig forklare, hvorfor alle tre svar faktisk er rigtige - ligesom den måde, du har udarbejdet det på.

Jeg har inkluderet eksempler på alle tre svar og det skema, de arbejder på:

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)

(bunke indsæt udsagn)

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)

Et skæringspunkt bruger to udvalgte udsagn og bringer matchende resultater tilbage. I dette tilfælde leder du efter alle de rækker, der har en matchende farve "Lysegul".

Jeg kan ikke give dig et eksempel i MySQL, da det ikke understøtter det (Som du kan se nedenfor, er det ikke nødvendigt for at give de samme resultater).

En foreningsforespørgsel med to udvalgte sætninger hver med en where-sætning, der kun tillader farven 'Lysegul', vil returnere de samme data. Selvom en union kan bruges til at returnere data, der ikke stemmer overens, betyder where-sætningen i hver select-sætning, at den faktisk kun returnerer de rækker, du ønsker.

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, det er slemt ikke? Vi specificerede selvfølgelig ikke where-sætningen:

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)

En sammenføjning mellem to tabeller på farven vil give dig mulighed for at returnere rækkerne fra begge tabeller i en enkelt række data. Du kan angive sammenføjningen på de to tabeller for elementfarven og bruge en where-klausul til kun at returnere de rækker, du leder efter.

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)

Som du kan se, har dette kun returneret rækkerne med en matchende farve og givet dig mulighed for at have kolonner fra begge tabeller i en enkelt række i dit resultatsæt.

Nu planlagde jeg tydeligvis ikke dette særlig godt, da jeg ikke har andre matchende resultater bortset fra 'Lysegule' i begge tabeller, så hvis jeg tilføjer et par flere poster i, får vi dette:

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 kan vi køre det igen, og denne gang får vi:

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)

Åh nej!

Det er nu, vi bruger join- og where-klausulen sammen:

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)

Ser du, i SQL er der ofte flere måder at få det samme resultat på på forskellige måder, end der er variationer af de samme data i dine tabeller.

Rediger:Okay, så hvis du kun vil have rækker hvor alle dataene matcher, skal du blot inkludere dem i joinsyntaksen:

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)

Som du kan se, fortæller vi nu joinforbindelsen, at både id og color felter skal matche mellem de to tabeller - og resultaterne taler for sig selv. Nu, i dette tilfælde, er jeg teknisk set stadig matchede ikke ALLE kolonnerne, da materialet er forskelligt. Hvis du ville matche yderligere, ville forespørgslen ikke returnere nogen resultater, da jeg ikke har nogen matchende poster, hvor id, materiale OG farve matcher, men syntaksen ville være som følger:

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)

Med den bemærkning vil du dog i de fleste tilfælde ikke have alle kolonnerne til at matche. Meget ofte har tabeller et ID, der kun bruges til den tabel og er en automatisk stigende værdi. Du vil bruge den til at identificere en unik række i den tabel, men ikke at bruge den til at matche ikke-relaterede tabeller. Hvis noget, ville jeg have foreslået, at du matcher på materiale og farve - men lad ID'et blive ude af det.



  1. sammenføj to forskellige tabeller og fjern duplikerede poster

  2. Sådan beregnes vækst i procent måned for måned i MySQL

  3. Synkronisering af SQL Server 2008-databaser over HTTP ved hjælp af WCF &Sync Framework

  4. SQL Server SELECT ind i eksisterende tabel