sql >> Databáze >  >> RDS >> PostgreSQL

Vytváření dotazu, který vrací id, pokud se podmínka shoduje v řádcích ze dvou tabulek

Přečetli jste si vaše otázka na Meta ohledně této konkrétní otázky, dovolte mi vysvětlit, proč jsou všechny tři odpovědi skutečně správné – stejně jako způsob, jakým jste to vyřešili.

Zahrnul jsem příklady všech tří odpovědí a schématu, na kterém pracují:

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)

(hromada vložených příkazů)

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)

Průnik používá dva příkazy select a vrací odpovídající výsledky. V tomto případě hledáte všechny řádky, které mají odpovídající barvu „světle žlutá“.

Nemohu vám dát příklad v MySQL, protože to nepodporuje (Jak můžete vidět níže, není potřeba, aby poskytoval stejné výsledky).

Sjednocovací dotaz dvou výběrových příkazů, každý s klauzulí where povolující pouze barvu „světle žlutá“, vrátí stejná data. Ačkoli sjednocení lze použít k vrácení dat, která se neshodují, klauzule where v každém příkazu select znamená, že vrátí pouze řádky, které chcete.

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, to je špatné, že? Samozřejmě jsme nespecifikovali klauzuli 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)

Spojení mezi dvěma tabulkami v barvě vám umožní vrátit řádky z obou tabulek v jediném řádku dat. Můžete určit spojení na dvou tabulkách pro barvu položky a použít klauzuli where k vrácení pouze řádků, které hledáte.

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)

Jak můžete vidět, vrátilo to pouze řádky se shodnou barvou a umožnilo vám mít sloupce z obou tabulek v jednom řádku vaší sady výsledků.

Zjevně jsem to nenaplánoval příliš dobře, protože nemám žádné jiné odpovídající výsledky kromě „Světle žluté“ v obou tabulkách, takže když přidám několik dalších položek, dostaneme toto:

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)

Nyní to můžeme spustit znovu a tentokrát dostaneme:

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)

Ach ne!

Zde nyní společně používáme spojení a klauzuli 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)

Vidíte, v SQL je často více způsobů, jak získat stejný výsledek různými prostředky, než jsou varianty stejných dat ve vašich tabulkách.

Edit:Dobře, takže pokud chcete pouze řádky, kde jsou vše data se shodují, stačí je zahrnout do syntaxe spojení:

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)

Jak můžete vidět, nyní říkáme spojení, že oba id a color pole se musí mezi dvěma tabulkami shodovat – a výsledky mluví samy za sebe. Nyní v tomto případě technicky stále neodpovídaly VŠEM sloupcům, protože materiál je jiný. Pokud byste chtěli provést shodu dále, dotaz by nevrátil žádné výsledky, protože nemám žádné odpovídající záznamy, kde by se id, materiál A barva shodovaly, ale syntaxe by byla následující:

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)

V tomto ohledu však ve většině případů nechcete vše sloupce, které se mají shodovat. Tabulky mají velmi často ID, které se používá pouze pro danou tabulku a je automaticky narůstající hodnotou. Chcete jej použít k identifikaci jedinečného řádku v tom tabulku, ale nepoužívat ji k přiřazení nesouvisejících tabulek. Pokud něco, navrhl bych, abyste se shodli na materiálu a barvě - ale vynechejte z toho ID.



  1. Geo vzdálenost MySQL

  2. MySQL - Můžete získat výchozí hodnotu sloupce?

  3. Stále dostávám chybový vztah [TABLE] neexistuje

  4. ORA-00904 Neplatný identifikátor” pro identifikátor ve skupině podle klauzule