PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tạo truy vấn trả về id nếu điều kiện được khớp trong các hàng từ hai bảng

Đã đọc câu hỏi của bạn trên Meta về câu hỏi cụ thể này, hãy để tôi giải thích lý do tại sao cả ba câu trả lời đều đúng - như cách bạn đã giải quyết.

Tôi đã bao gồm các ví dụ về cả ba câu trả lời và lược đồ mà chúng đang làm việc:

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)

(nhiều câu lệnh chèn)

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)

Một giao điểm sử dụng hai câu lệnh chọn và trả lại kết quả phù hợp. Trong trường hợp này, bạn đang tìm kiếm tất cả các hàng có màu phù hợp là 'Vàng nhạt'.

Tôi không thể cung cấp cho bạn một ví dụ trong MySQL vì nó không hỗ trợ nó (Như bạn có thể thấy bên dưới, nó không cần thiết để đưa ra kết quả tương tự).

Một truy vấn liên hợp gồm hai câu lệnh chọn, mỗi câu lệnh có mệnh đề where chỉ cho phép màu 'Vàng nhạt' sẽ trả về cùng một dữ liệu. Mặc dù liên hợp có thể được sử dụng để trả về dữ liệu không khớp, mệnh đề where trong mỗi câu lệnh select có nghĩa là nó sẽ chỉ trả về các hàng mà bạn muốn.

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, thật tệ phải không? Tất nhiên, chúng tôi không chỉ định mệnh đề 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)

Phép nối giữa hai bảng trên màu sẽ cho phép bạn trả về các hàng từ cả hai bảng trong một hàng dữ liệu. Bạn có thể chỉ định phép nối trên hai bảng cho màu mục và sử dụng mệnh đề where để chỉ trả về các hàng bạn đang tìm kiếm.

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)

Như bạn có thể thấy, điều này chỉ trả về các hàng có màu phù hợp và cho phép bạn có các cột từ cả hai bảng trong một hàng duy nhất trong tập kết quả của mình.

Bây giờ, tôi rõ ràng không lập kế hoạch này tốt lắm vì tôi không có kết quả phù hợp nào khác ngoài 'Màu vàng nhạt' trong cả hai bảng, vì vậy nếu tôi thêm một vài mục nhập nữa vào, chúng tôi nhận được kết quả này:

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)

Bây giờ chúng ta có thể chạy lại và lần này nhận được:

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)

Ồ không!

Đây là lúc chúng ta sử dụng phép nối và mệnh đề where cùng nhau:

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)

Bạn thấy đấy, trong SQL thường có nhiều cách để nhận được cùng một kết quả thông qua các phương tiện khác nhau hơn là các biến thể của cùng một dữ liệu trong các bảng của bạn.

Chỉnh sửa:Được rồi, vì vậy nếu bạn chỉ muốn các hàng có tất cả dữ liệu khớp, chỉ cần đưa nó vào cú pháp nối:

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)

Như bạn có thể thấy, bây giờ chúng tôi nói với tham gia rằng cả idcolor các trường phải khớp giữa hai bảng - và kết quả tự nói lên. Bây giờ, trong trường hợp này, về mặt kỹ thuật, tôi vẫn vẫn không khớp với TẤT CẢ các cột vì vật liệu khác nhau. Nếu bạn muốn so khớp thêm, truy vấn sẽ không trả về bất kỳ kết quả nào vì tôi không có bản ghi nào phù hợp trong đó id, vật liệu VÀ màu khớp với nhau, nhưng cú pháp sẽ như sau:

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)

Tuy nhiên, lưu ý rằng bạn trong hầu hết các trường hợp, bạn không muốn tất cả các cột để phù hợp. Các bảng rất thường có một ID chỉ được sử dụng cho bảng đó và là một giá trị tự động tăng dần. Bạn muốn sử dụng nó để xác định một hàng duy nhất trong that bảng, nhưng không sử dụng nó để khớp các bảng không liên quan. Nếu có điều gì đó, tôi sẽ đề nghị bạn kết hợp về chất liệu và màu sắc - nhưng hãy bỏ qua 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. Làm thế nào để đếm các hàng liên quan bao gồm các danh mục con?

  2. CẬP NHẬT / CHÈN dựa trên nếu một hàng tồn tại

  3. Làm cách nào để định dạng trường bigint thành ngày tháng trong Postgresql?

  4. không có mục nhập pg_hba.conf cho máy chủ

  5. Cải thiện tốc độ truy vấn:SELECT đơn giản trong bảng postgres lớn