PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Създаване на заявка, която връща id, ако условието съответства в редове от две таблици

Прочетохте вашият въпрос на Meta относно този конкретен въпрос, позволете ми да обясня защо и трите отговора наистина са верни - както и начинът, по който го разработихте.

Включих примери и за трите отговора и схемата, по която работят:

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)

(група изрази за вмъкване)

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)

Пресичането използва два оператора за избор и връща съвпадащи резултати. В този случай вие търсите всички редове, които имат съответстващ цвят на „Светло жълто“.

Не мога да ви дам пример в MySQL, тъй като не го поддържа (Както можете да видите по-долу, не е необходимо, за да даде същите резултати).

Заявка за обединение на два оператора за избор, всеки с клауза where, позволяваща само цвета на „светло жълто“, ще върне същите данни. Въпреки че може да се използва обединение за връщане на данни, които не съвпадат, клаузата where във всеки оператор select означава, че той наистина ще върне само редовете, които искате.

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)

Уау, това е лошо, нали? Разбира се, не сме посочили клаузата 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)

Съединението между две таблици по цвят ще ви позволи да върнете редовете от двете таблици в един ред от данни. Можете да укажете свързването на двете таблици за цвета на елемента и да използвате клауза where, за да върнете само редовете, които търсите.

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)

Както можете да видите, това върна само редовете със съответстващ цвят и ви позволи да имате колони от двете таблици в един ред от вашия набор от резултати.

Очевидно не планирах това много добре, тъй като нямам други съвпадащи резултати освен „Светло жълто“ в двете таблици, така че ако добавя още няколко записа, получаваме това:

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)

Сега можем да изпълним това отново и този път да получим:

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)

О, не!

Тук сега използваме заедно клаузата join и 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)

Виждате ли, в SQL често има повече начини да получите същия резултат чрез различни средства, отколкото има вариации на едни и същи данни във вашите таблици.

Редактиране:Добре, така че ако искате само редове, където всички данните съвпадат, просто ги включете в синтаксиса за присъединяване:

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)

Както можете да видите, сега казваме на присъединяването, че и id и color полетата трябва да съвпадат между двете таблици - и резултатите говорят сами за себе си. Сега, в този случай, аз технически все още не съответства на ВСИЧКИ колони, тъй като материалът е различен. Ако искате да съпоставите допълнително, заявката няма да върне никакви резултати, тъй като нямам съвпадащи записи, където ID, материалът И цветът съвпадат, но синтаксисът ще бъде както следва:

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)

В тази бележка обаче вие ​​в повечето случаи не искате всички колоните да съвпадат. Много често таблиците имат идентификатор, който се използва само за тази таблица и е автоматично нарастваща стойност. Искате да го използвате, за да идентифицирате уникален ред в that таблица, но не и да я използвате за съвпадение на несвързани таблици. Ако не друго, щях да препоръчам да съвпадате по материал и цвят, но не включвайте ID.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изпълнение на множество екземпляри на PostgreSQL на един хост

  2. psycopg2.OperationalError:ФАТАЛНО:неподдържан интерфейсен протокол 1234.5679:сървърът поддържа от 2.0 до 3.0

  3. clojure.java.jdbc мързелива заявка

  4. свързване на postgresql и codeigniter

  5. Използвайте низ [][] с ngpsql