SQL THAM GIA và các loại THAM GIA khác nhau


Câu trả lời:


330

Một minh họa từ W3schools :


THAM GIA THAM GIA - Chỉ các bản ghi phù hợp với điều kiện trong cả hai bảng


THAM GIA TRÁI PHIẾU - Tất cả các bản ghi từ bảng 1 kết hợp với các bản ghi khớp với điều kiện trong bảng 2


RIGHT THAM GIA - Tất cả các bản ghi từ bảng 2 kết hợp với các bản ghi từ bảng 1 phù hợp với điều kiện


FULL OUTER THAM GIA - Kết hợp cả hai liên kết ngoài trái và phải khớp với mệnh đề ON nhưng bảo toàn cả hai bảng



27
@KNU Các w3fools nên cung cấp tín dụng từ nơi họ đã lấy ý tưởng cho các bức ảnh. Xem phần trực quan hóa SQL tham gia của Jeff Atwood (vâng, người đồng tác giả SO) và bài viết được liên kết của Ligaya Turmelle nơi Jeff có ý tưởng và đưa ra ý tưởng đó.
ypercubeᵀᴹ

2
@avi tham gia trái và phải tương tự nhau, nếu bạn không bận tâm thì đó là bảng chính mà tham gia dựa trên.
Anup

2
@philipxy: Đó là một định nghĩa kỳ lạ (ngay cả khi bạn đúng). Nhưng tôi muốn đi theo cách khác và bắt đầu với tham gia chéo và sau đó "xây dựng" tham gia bên trong trên đầu trang. Rốt cuộc, khái niệm đơn thuần về tham gia chéo làm mất hiệu lực các trực quan biểu đồ Venn không chính xác và không chính xác này ...
Lukas Eder

1
Những hình ảnh này dường như ngụ ý rằng sự kết hợp giống như tham gia bên ngoài đầy đủ và giao điểm giống như tham gia bên trong không đúng như tôi biết.
mightyWOZ

1
@DevDave, vì trái với niềm tin phổ biến - một bức tranh không đáng giá ngàn lời nói. Xem câu trả lời tiếp theo.
hyankov

248

SQL JOIN

SQL JOIN là một phương thức để lấy dữ liệu từ hai hoặc nhiều bảng cơ sở dữ liệu.

Các SQL JOINs khác nhau là gì?

Có tổng cộng năm JOINs. Họ đang :

  1. JOIN or INNER JOIN
  2. OUTER JOIN

     2.1 LEFT OUTER JOIN or LEFT JOIN
     2.2 RIGHT OUTER JOIN or RIGHT JOIN
     2.3 FULL OUTER JOIN or FULL JOIN

  3. NATURAL JOIN
  4. CROSS JOIN
  5. SELF JOIN

1. THAM GIA hoặc THAM GIA THAM GIA:

Trong loại này JOIN, chúng tôi nhận được tất cả các bản ghi khớp với điều kiện trong cả hai bảng và các bản ghi trong cả hai bảng không khớp đều không được báo cáo.

Nói cách khác, INNER JOINdựa trên một thực tế duy nhất là: CHỈ các mục phù hợp trong CẢ HAI các bảng NÊN được liệt kê.

Lưu ý rằng một JOINmà không cần bất kỳ khác JOINtừ khóa (như INNER, OUTER, LEFT, vv) là một INNER JOIN. Nói cách khác, JOINlà một đường cú pháp cho INNER JOIN(xem: Sự khác biệt giữa THAM GIA và THAM GIA VÀO ).

2. THAM GIA NGOÀI:

OUTER JOIN lấy

Hoặc, các hàng được khớp từ một bảng và tất cả các hàng trong bảng khác Hoặc, tất cả các hàng trong tất cả các bảng (không quan trọng có khớp hay không).

Có ba loại Tham gia ngoài:

2.1 LEFT OUTER THAM GIA hoặc TRÁI THAM GIA

Phép nối này trả về tất cả các hàng từ bảng bên trái kết hợp với các hàng khớp từ bảng bên phải. Nếu không có cột nào khớp trong bảng bên phải, nó sẽ trả về NULLgiá trị.

2.2 RIGHT OUTER THAM GIA hoặc RIGHT THAM GIA

Điều này JOINtrả về tất cả các hàng từ bảng bên phải kết hợp với các hàng phù hợp từ bảng bên trái. Nếu không có cột nào khớp trong bảng bên trái, nó sẽ trả về NULLgiá trị.

2.3 FULL OUTER THAM GIA hoặc FULL THAM GIA

Điều này JOINkết hợp LEFT OUTER JOINRIGHT OUTER JOIN. Nó trả về các hàng từ một trong hai bảng khi các điều kiện được đáp ứng và trả về NULLgiá trị khi không có kết quả khớp.

Nói cách khác, OUTER JOINdựa trên thực tế rằng: CHỈ các mục phù hợp trong MỘT TRONG các bảng (ĐÚNG hoặc TRÁI) hoặc CẢ HAI bảng (ĐẦY ĐỦ) NÊN được liệt kê.

Note that `OUTER JOIN` is a loosened form of `INNER JOIN`.

3. THAM GIA TỰ NHIÊN:

Nó dựa trên hai điều kiện:

  1. những JOINđược thực hiện trên tất cả các cột có cùng tên cho bình đẳng.
  2. Loại bỏ các cột trùng lặp từ kết quả.

Điều này có vẻ mang tính lý thuyết nhiều hơn và do đó, có lẽ (hầu hết) DBMS thậm chí không bận tâm đến việc hỗ trợ này.

4. THAM GIA CROSS:

Đây là sản phẩm của Cartesian trong hai bảng liên quan. Kết quả của một CROSS JOINý chí sẽ không có ý nghĩa trong hầu hết các tình huống. Hơn nữa, chúng tôi sẽ không cần điều này cả (hoặc cần ít nhất, chính xác).

5. TỰ THAM GIA:

Nó không phải là một hình thức khác nhau của JOIN, chứ không phải nó là một JOIN( INNER, OUTER, vv) của một bảng với chính nó.

THAM GIA dựa trên các nhà khai thác

Tùy thuộc vào toán tử được sử dụng cho một JOINmệnh đề, có thể có hai loại JOINs. họ đang

  1. THAM GIA
  2. THAM GIA

1. Equi THAM GIA:

Đối với bất kỳ JOINloại nào ( INNER,, OUTERv.v.), nếu chúng ta chỉ sử dụng toán tử đẳng thức (=), thì chúng ta nói rằng đó JOINlà một EQUI JOIN.

2. THAM GIA:

Điều này giống như EQUI JOINnhưng nó cho phép tất cả các toán tử khác như>, <,> = vv

Nhiều người coi cả hai EQUI JOINvà Theta JOINtương tự INNER, OUTER vv JOINs. Nhưng tôi tin tưởng mạnh mẽ rằng đó là một sai lầm và làm cho các ý tưởng trở nên mơ hồ. Bởi vì INNER JOIN, OUTER JOINv.v ... tất cả đều được kết nối với các bảng và dữ liệu của chúng trong khi EQUI JOINTHETA JOINchỉ được kết nối với các toán tử mà chúng ta sử dụng trước đây.

Một lần nữa, có nhiều người coi đó NATURAL JOINlà một loại "kỳ dị" EQUI JOIN. Trong thực tế, đó là sự thật, vì điều kiện đầu tiên tôi đề cập đến NATURAL JOIN. Tuy nhiên, chúng tôi không phải hạn chế chỉ đơn giản NATURAL JOINlà một mình. INNER JOINs, OUTER JOINs vv có thể là một EQUI JOINquá.


2
Có THAM GIA
LATITH

13
Mặc dù điều này có vẻ hợp lý, tôi không nghĩ câu trả lời "tham gia SQL là gì" theo bất kỳ cách nào truyền tải thông tin hữu ích. Câu trả lời nói chung là một tài liệu tham khảo được viết cho những người đã hiểu về tham gia, không dành cho những người đang hỏi những câu hỏi đó. Nó cũng bỏ qua các tài liệu tham khảo, cả hai để hỗ trợ cho tuyên bố của mình (nếu phù hợp nếu đưa ra câu trả lời có thẩm quyền) và để cung cấp giải thích bổ sung thông qua các tài nguyên bên ngoài. Nếu bạn đang cố gắng viết một câu trả lời có thẩm quyền để liên kết người dùng SQL mới với, có thể đáng để điền vào chỗ trống một chút, đặc biệt là phần "tham gia là gì".
Craig Ringer

bạn có thể cung cấp một số ví dụ?
avi

67

Định nghĩa:


THAM GIA là cách để truy vấn dữ liệu kết hợp cùng một lúc từ nhiều bảng.

Các loại THAM GIA:


Mối quan tâm đến RDBMS có 5 loại liên kết:

  • Equi-Join: Kết hợp các bản ghi chung từ hai bảng dựa trên điều kiện bình đẳng. Về mặt kỹ thuật, Tham gia được thực hiện bằng cách sử dụng toán tử đẳng thức (=) để so sánh các giá trị của Khóa chính của một bảng và các giá trị Khóa ngoài của một bảng khác, do đó tập kết quả bao gồm các bản ghi chung (khớp) từ cả hai bảng. Để thực hiện, xem INNER-THAM GIA.

  • Tham gia tự nhiên: Đây là phiên bản nâng cao của Equi-Join, trong đó thao tác CHỌN bỏ qua cột trùng lặp. Để thực hiện, xem INNER-THAM GIA

  • Không tham gia Equi-Join: Nó ngược lại với Equi-jo trong đó điều kiện tham gia được sử dụng khác với toán tử bằng (=), ví dụ: =, <=,> =,>, <hoặc GIỮA, v.v. Để thực hiện, hãy xem INNER-THAM GIA.

  • Tự tham gia :: Một hành vi tùy chỉnh tham gia trong đó một bảng kết hợp với chính nó; Điều này thường là cần thiết để truy vấn các bảng tự tham chiếu (hoặc thực thể mối quan hệ Unary). Để thực hiện, xem INNER-THAM GIA.

  • Sản phẩm Cartesian: Nó kết hợp chéo tất cả các bản ghi của cả hai bảng mà không có bất kỳ điều kiện. Về mặt kỹ thuật, nó trả về tập kết quả của một truy vấn mà không có WHERE-Article.

Theo sự quan tâm và tiến bộ của SQL, có 3 loại liên kết và tất cả các phép nối RDBMS có thể đạt được bằng cách sử dụng các loại liên kết này.

  1. INNER-THAM GIA: Nó hợp nhất (hoặc kết hợp) các hàng khớp từ hai bảng. Việc khớp được thực hiện dựa trên các cột chung của bảng và hoạt động so sánh của chúng. Nếu điều kiện dựa trên sự bình đẳng thì: Đã thực hiện THIẾT BỊ-THAM GIA, nếu không thì không tham gia.

  2. OUTER-THAM GIA: Nó kết hợp (hoặc kết hợp) hàng xuất từ hai bảng và các hàng chưa từng có với các giá trị NULL. Tuy nhiên, có thể tùy chỉnh lựa chọn các hàng không khớp, ví dụ: chọn hàng chưa khớp từ bảng đầu tiên hoặc bảng thứ hai theo loại phụ: LEFT OUTER THAM GIA và RIGHT OUTER THAM GIA.

    2.1. LEFT Outer THAM GIA (còn gọi là LEFT-THAM GIA): Chỉ trả về các hàng khớp từ hai bảng và không khớp với bảng LEFT (tức là bảng đầu tiên).

    2.2. RIGHT Outer THAM GIA (hay còn gọi là RIGHT-THAM GIA): Trả về các hàng khớp từ hai bảng và không khớp với chỉ bảng RIGHT.

    2.3. FULL OUTER THAM GIA (còn gọi là OUTER THAM GIA): Trả về khớp và không khớp từ cả hai bảng.

  3. CROSS-THAM GIA: Sự tham gia này không hợp nhất / kết hợp thay vào đó nó thực hiện sản phẩm của Cartesian.

nhập mô tả hình ảnh ở đây Lưu ý: Tự THAM GIA có thể đạt được bằng INNER-THAM GIA, NGOÀI-THAM GIA và CROSS-THAM GIA dựa trên yêu cầu nhưng bảng phải tham gia với chính nó.

Để biết thêm thông tin:

Ví dụ:

1.1: INNER-THAM GIA: Thực hiện Equi-tham gia

SELECT  *
FROM Table1 A 
 INNER JOIN Table2 B ON A.<Primary-Key> =B.<Foreign-Key>;

1.2: INNER-THAM GIA: Thực hiện tự nhiên-THAM GIA

Select A.*, B.Col1, B.Col2          --But no B.ForeignKeyColumn in Select
 FROM Table1 A
 INNER JOIN Table2 B On A.Pk = B.Fk;

1.3: INNER-THAM GIA với triển khai NON-Equi-tham gia

Select *
 FROM Table1 A INNER JOIN Table2 B On A.Pk <= B.Fk;

1.4: THAM GIA-THAM GIA với TỰ TIN

Select *
 FROM Table1 A1 INNER JOIN Table1 A2 On A1.Pk = A2.Fk;

2.1: OUTER THAM GIA (tham gia đầy đủ bên ngoài)

Select *
 FROM Table1 A FULL OUTER JOIN Table2 B On A.Pk = B.Fk;

2.2: THAM GIA

Select *
 FROM Table1 A LEFT OUTER JOIN Table2 B On A.Pk = B.Fk;

2.3: THAM GIA QUYỀN

Select *
 FROM Table1 A RIGHT OUTER JOIN Table2 B On A.Pk = B.Fk;

3.1: THAM GIA CROSS

Select *
 FROM TableA CROSS JOIN TableB;

3.2: THAM GIA CROSS-Tự tham gia

Select *
 FROM Table1 A1 CROSS JOIN Table1 A2;

//HOẶC LÀ//

Select *
 FROM Table1 A1,Table1 A2;

Các nhãn "Bảng 1" & "Bảng 2" và các nhãn bên dưới không phù hợp, chúng là từ minh họa của intersect/ except/ union; ở đây các vòng tròn là các hàng được trả về bởi left& right join, như các nhãn được đánh số. Hình ảnh AXB là vô nghĩa. cross join= inner join on 1=1& là trường hợp đặc biệt của sơ đồ đầu tiên.
philipxy

Điều đáng nói là SQL-92 định nghĩa UNION JOIN. Bây giờ đã lỗi thời trong SQL: 2003.
Impaler

40

Điều thú vị là hầu hết các câu trả lời khác đều gặp phải hai vấn đề này:

Gần đây tôi đã viết một bài viết về chủ đề: Hướng dẫn toàn diện, có thể chưa hoàn chỉnh về nhiều cách khác nhau để tham gia các bảng trong SQL , mà tôi sẽ tóm tắt ở đây.

Đầu tiên và quan trọng nhất: THAM GIA là các sản phẩm của cartesian

Đây là lý do tại sao các sơ đồ Venn giải thích chúng không chính xác, bởi vì THAM GIA tạo ra một sản phẩm cartesian giữa hai bảng được nối. Wikipedia minh họa nó độc đáo:

nhập mô tả hình ảnh ở đây

Cú pháp SQL cho các sản phẩm cartesian là CROSS JOIN. Ví dụ:

SELECT *

-- This just generates all the days in January 2017
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Here, we're combining all days with all departments
CROSS JOIN departments

Kết hợp tất cả các hàng từ một bảng với tất cả các hàng từ bảng khác:

Nguồn:

+--------+   +------------+
| day    |   | department |
+--------+   +------------+
| Jan 01 |   | Dept 1     |
| Jan 02 |   | Dept 2     |
| ...    |   | Dept 3     |
| Jan 30 |   +------------+
| Jan 31 |
+--------+

Kết quả:

+--------+------------+
| day    | department |
+--------+------------+
| Jan 01 | Dept 1     |
| Jan 01 | Dept 2     |
| Jan 01 | Dept 3     |
| Jan 02 | Dept 1     |
| Jan 02 | Dept 2     |
| Jan 02 | Dept 3     |
| ...    | ...        |
| Jan 31 | Dept 1     |
| Jan 31 | Dept 2     |
| Jan 31 | Dept 3     |
+--------+------------+

Nếu chúng ta chỉ viết một danh sách các bảng được phân tách bằng dấu phẩy, chúng ta sẽ nhận được cùng một:

-- CROSS JOINing two tables:
SELECT * FROM table1, table2

THAM GIA THAM GIA (Theta-THAM GIA)

An INNER JOINchỉ là một CROSS JOINbộ lọc trong đó vị từ bộ lọc được gọi Thetatrong đại số quan hệ.

Ví dụ:

SELECT *

-- Same as before
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Now, exclude all days/departments combinations for
-- days before the department was created
JOIN departments AS d ON day >= d.created_at

Lưu ý rằng từ khóa INNERlà tùy chọn (ngoại trừ trong MS Access).

( nhìn vào bài báo cho ví dụ kết quả )

THIẾT BỊ THAM GIA

Một loại Theta-THAM GIA đặc biệt là Equi THAM GIA, mà chúng tôi sử dụng nhiều nhất. Vị ngữ kết hợp khóa chính của một bảng với khóa ngoại của bảng khác. Nếu chúng ta sử dụng cơ sở dữ liệu Sakila để minh họa, chúng ta có thể viết:

SELECT *
FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id

Điều này kết hợp tất cả các diễn viên với bộ phim của họ.

Hoặc cũng có thể, trên một số cơ sở dữ liệu:

SELECT *
FROM actor
JOIN film_actor USING (actor_id)
JOIN film USING (film_id)

Các USING()cú pháp cho phép xác định một cột đó phải có mặt ở hai bên của lệnh JOIN bảng hoạt động và tạo ra một vị bình đẳng trên hai cột.

THAM GIA TỰ NHIÊN

Các câu trả lời khác đã liệt kê riêng loại "THAM GIA" này, nhưng điều đó không có ý nghĩa. Đây chỉ là một dạng cú pháp cho Equi THAM GIA, đây là trường hợp đặc biệt của Theta-THAM GIA hoặc INNER THAM GIA. NATURAL THAM GIA chỉ đơn giản là thu thập tất cả các cột chung cho cả hai bảng được nối và nối USING()các cột đó. Điều này hầu như không bao giờ hữu ích, vì các kết LAST_UPDATEquả trùng khớp ngẫu nhiên (như các cột trong cơ sở dữ liệu Sakila ).

Đây là cú pháp:

SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film

THAM GIA

Bây giờ, OUTER JOINcó một chút khác biệt so INNER JOINvới khi nó tạo ra một UNIONsố sản phẩm cartesian. Chúng tôi có thể viết:

-- Convenient syntax:
SELECT *
FROM a LEFT JOIN b ON <predicate>

-- Cumbersome, equivalent syntax:
SELECT a.*, b.*
FROM a JOIN b ON <predicate>
UNION ALL
SELECT a.*, NULL, NULL, ..., NULL
FROM a
WHERE NOT EXISTS (
  SELECT * FROM b WHERE <predicate>
)

Không ai muốn viết cái sau, vì vậy chúng tôi viết OUTER JOIN(thường được tối ưu hóa tốt hơn bởi cơ sở dữ liệu).

Giống như INNER, từ khóa OUTERlà tùy chọn, ở đây.

OUTER JOIN có ba hương vị:

  • LEFT [ OUTER ] JOIN: Bảng bên trái của JOINbiểu thức được thêm vào liên minh như được hiển thị ở trên.
  • RIGHT [ OUTER ] JOIN: Bảng bên phải của JOINbiểu thức được thêm vào liên minh như được hiển thị ở trên.
  • FULL [ OUTER ] JOIN: Cả hai bảng của JOINbiểu thức được thêm vào liên minh như được hiển thị ở trên.

Tất cả những thứ này có thể được kết hợp với từ khóa USING()hoặc với NATURAL( Tôi thực sự đã có một trường hợp sử dụng trong thế giới thực NATURAL FULL JOINgần đây )

Cú pháp thay thế

Có một số cú pháp lịch sử, không dùng nữa trong Oracle và SQL Server, đã được hỗ trợ OUTER JOINtrước khi tiêu chuẩn SQL có cú pháp cho việc này:

-- Oracle
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)

-- SQL Server
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id

Đã nói như vậy, không sử dụng cú pháp này. Tôi chỉ liệt kê điều này ở đây để bạn có thể nhận ra nó từ các bài đăng blog cũ / mã kế thừa.

Phân vùng OUTER JOIN

Ít người biết điều này, nhưng tiêu chuẩn SQL chỉ định phân vùng OUTER JOIN(và Oracle thực hiện nó). Bạn có thể viết những thứ như thế này:

WITH

  -- Using CONNECT BY to generate all dates in January
  days(day) AS (
    SELECT DATE '2017-01-01' + LEVEL - 1
    FROM dual
    CONNECT BY LEVEL <= 31
  ),

  -- Our departments
  departments(department, created_at) AS (
    SELECT 'Dept 1', DATE '2017-01-10' FROM dual UNION ALL
    SELECT 'Dept 2', DATE '2017-01-11' FROM dual UNION ALL
    SELECT 'Dept 3', DATE '2017-01-12' FROM dual UNION ALL
    SELECT 'Dept 4', DATE '2017-04-01' FROM dual UNION ALL
    SELECT 'Dept 5', DATE '2017-04-02' FROM dual
  )
SELECT *
FROM days 
LEFT JOIN departments 
  PARTITION BY (department) -- This is where the magic happens
  ON day >= created_at

Các phần của kết quả:

+--------+------------+------------+
| day    | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1     |            | -- Didn't match, but still get row
| Jan 02 | Dept 1     |            | -- Didn't match, but still get row
| ...    | Dept 1     |            | -- Didn't match, but still get row
| Jan 09 | Dept 1     |            | -- Didn't match, but still get row
| Jan 10 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 11 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 12 | Dept 1     | Jan 10     | -- Matches, so get join result
| ...    | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 31 | Dept 1     | Jan 10     | -- Matches, so get join result

Vấn đề ở đây là tất cả các hàng từ phía được phân vùng của phép nối sẽ kết thúc trong kết quả bất kể có JOINkhớp với bất cứ thứ gì ở "phía bên kia của THAM GIA" hay không. Câu chuyện dài: Đây là để điền vào dữ liệu thưa thớt trong các báo cáo. Rất hữu ích!

THAM GIA SEMI

Nghiêm túc? Không có câu trả lời khác có điều này? Tất nhiên là không, vì nó không có cú pháp riêng trong SQL, thật không may (giống như ANTI THAM GIA bên dưới). Nhưng chúng ta có thể sử dụng IN()EXISTS(), ví dụ để tìm tất cả các diễn viên đã đóng trong các bộ phim:

SELECT *
FROM actor a
WHERE EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

Vị WHERE a.actor_id = fa.actor_idngữ đóng vai trò là vị ngữ bán tham gia. Nếu bạn không tin, hãy xem kế hoạch thực hiện, ví dụ như trong Oracle. Bạn sẽ thấy rằng cơ sở dữ liệu thực hiện một hoạt động SEMI THAM GIA, không phải là EXISTS()vị ngữ.

nhập mô tả hình ảnh ở đây

THAM GIA

Đây mới chỉ là đối diện của BÁN JOIN ( cẩn thận không để sử dụng NOT INmặc dù , vì nó có một caveat quan trọng)

Dưới đây là tất cả các diễn viên không có phim:

SELECT *
FROM actor a
WHERE NOT EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

Một số người (đặc biệt là người MySQL) cũng viết ANTI THAM GIA như thế này:

SELECT *
FROM actor a
LEFT JOIN film_actor fa
USING (actor_id)
WHERE film_id IS NULL

Tôi nghĩ lý do lịch sử là hiệu suất.

THAM GIA

OMG, cái này quá tuyệt Tôi là người duy nhất đề cập đến nó? Đây là một truy vấn thú vị:

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
LEFT OUTER JOIN LATERAL (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  JOIN inventory AS i USING (film_id)
  JOIN rental AS r USING (inventory_id)
  JOIN payment AS p USING (rental_id)
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f
ON true

Nó sẽ tìm thấy TOP 5 doanh thu sản xuất phim cho mỗi diễn viên. Mỗi khi bạn cần một truy vấn TOP-N-per-Something, LATERAL JOINsẽ là bạn của bạn. Nếu bạn là người của SQL Server, thì bạn biết JOINloại này dưới tênAPPLY

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
OUTER APPLY (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa ON f.film_id = fa.film_id
  JOIN inventory AS i ON f.film_id = i.film_id
  JOIN rental AS r ON i.inventory_id = r.inventory_id
  JOIN payment AS p ON r.rental_id = p.rental_id
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f

OK, có lẽ đó là gian lận, bởi vì một LATERAL JOINhoặc APPLYbiểu thức thực sự là một "truy vấn con tương quan" tạo ra một số hàng. Nhưng nếu chúng ta cho phép "truy vấn con tương quan", chúng ta cũng có thể nói về ...

ĐA NĂNG

Điều này chỉ thực sự được thực hiện bởi Oracle và Informix (theo hiểu biết của tôi), nhưng nó có thể được mô phỏng trong PostgreQuery bằng cách sử dụng mảng và / hoặc XML và trong SQL Server bằng XML.

MULTISETtạo ra một truy vấn con tương quan và lồng tập hợp các hàng kết quả trong truy vấn bên ngoài. Truy vấn dưới đây chọn tất cả các diễn viên và cho mỗi diễn viên thu thập các bộ phim của họ trong một bộ sưu tập lồng nhau:

SELECT a.*, MULTISET (
  SELECT f.*
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  WHERE a.actor_id = fa.actor_id
) AS films
FROM actor

Như bạn đã thấy, có rất nhiều loại THAM GIA hơn chỉ là "nhàm chán" INNER, OUTERCROSS JOINrằng thường đề cập. Thêm chi tiết trong bài viết của tôi . Và xin vui lòng, ngừng sử dụng biểu đồ Venn để minh họa chúng.


Equijoin là trường hợp đặc biệt của theta-tham gia trong đó theta là bình đẳng. Theta-jo tương tự như một trường hợp đặc biệt của phép nối bên trong trong đó on là so sánh theta trên một cột từ mỗi cột. Vài thập kỷ sau khi Codd định nghĩa cho họ một số (các) sách giáo khoa định nghĩa sai theta tham gia như một sự khái quát hóa tương tự như tham gia bên trong.
philipxy

@philipxy: Bất cứ điều gì cụ thể tôi nên thay đổi trong câu trả lời của tôi? Bạn có thể đề xuất chỉnh sửa ...
Lukas Eder

10

Tôi đã tạo ra một minh họa giải thích tốt hơn lời nói, theo ý kiến ​​của tôi: Bảng giải thích SQL Tham gia


@Niraj Các vòng tròn A & B không chứa các hàng của A & B. Chúng được sao chép một cách mù quáng từ nơi khác mà không có tín dụng. Tham gia chéo được bao gồm trong trường hợp tham gia bên trong, đó là tham gia bên trong vào 1 = 1. Những phần này của bức tranh "hoàn hảo" theo cách nào?
philipxy

@philipxy Xin lỗi nhưng tôi không bận tâm về việc nếu nó được sao chép từ nơi khác. và tôi không chắc cái nào không đúng trong hình trên. Đối với tôi điều này là ok. Tham gia chéo không được mô tả ở đây. Nó không được bao gồm trong một tham gia nội bộ ..
Niraj

-3

Tôi sẽ đẩy peeve thú cưng của tôi: từ khóa SỬ DỤNG.

Nếu cả hai bảng ở cả hai phía của THAM GIA đều có khóa ngoại được đặt tên chính xác (nghĩa là cùng tên, không chỉ "id) thì có thể sử dụng bảng này:

SELECT ...
FROM customers JOIN orders USING (customer_id)

Tôi thấy điều này rất thực tế, dễ đọc và không được sử dụng thường xuyên.


2
Điều này không trả lời câu hỏi. Nó thuộc về một nhận xét hoặc theo câu hỏi hoặc một trong những câu trả lời.
TylerH
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.