- Tham gia bên trong là gì?
- Tham gia Bên ngoài là gì?
- Thực hiện các phép nối bên ngoài bằng ký hiệu (+)
Giống như hầu như tất cả các cơ sở dữ liệu quan hệ, Oracle cho phép tạo các truy vấn kết hợp hoặc JOIN
hàng từ hai bảng trở lên để tạo tập kết quả cuối cùng. Trong khi có rất nhiều loại trong số các phép nối có thể được thực hiện, phổ biến nhất là INNER JOIN
và OUTER JOIN
.
Trong hướng dẫn này, chúng ta sẽ khám phá ngắn gọn sự khác biệt giữa INNER
và OUTER JOIN
và sau đó kiểm tra phương thức viết tắt mà Oracle cung cấp để thực hiện OUTER JOINS
đặc biệt bằng cách sử dụng +
ký hiệu toán tử.
Tham gia bên trong là gì?
INNER JOIN
trong cơ sở dữ liệu quan hệ chỉ đơn giản là việc kết hợp hai hoặc nhiều bảng trong đó kết quả sẽ chỉ chứa dữ liệu thỏa mãn tất cả các điều kiện kết hợp .
Ví dụ:ở đây chúng tôi có một library
cơ bản lược đồ có hai bảng:books
và languages
. languages
bảng chỉ là danh sách các tên ngôn ngữ có thể có và một ngôn ngữ duy nhất id
:
SELECT * FROM library.languages;
id name
1 English
2 French
3 German
4 Mandarin
5 Spanish
6 Arabic
7 Japanese
8 Russian
9 Greek
10 Italian
Trong khi đó, books
của chúng tôi bảng có language_id
hàng mà đối với hầu hết, nhưng không phải tất cả, sách chỉ chứa language_id
được liên kết với ngôn ngữ xuất bản ban đầu của cuốn sách:
SELECT * FROM
books
ORDER BY
id
FETCH FIRST 10 ROWS ONLY;
id title author year_published language_id
1 In Search of Lost Time Marcel Proust 1913 2
2 Ulysses James Joyce 1922 1
3 Don Quixote Miguel de Cervantes 1605 5
4 Moby Dick Herman Melville 1851 1
5 Hamlet William Shakespeare 1601 (null)
6 War and Peace Leo Tolstoy 1869 8
7 The Odyssey Homer -700 9
8 The Great Gatsby F. Scott Fitzgerald 1925 1
9 The Divine Comedy Dante Alighieri 1472 10
10 Madame Bovary Gustave Flaubert 1857 2
Trong nhiều trường hợp, chúng tôi có thể muốn thực hiện INNER JOIN
của books
và languages
bảng để thay vì xem language_id
vô nghĩa giá trị của mỗi cuốn sách, chúng tôi thực sự có thể thấy language name
thay vào đó.
SELECT
b.id,
b.title,
b.author,
b.year_published,
l.name language
FROM
books b
INNER JOIN
library.languages l
ON
b.language_id = l.id
ORDER BY
b.id
FETCH FIRST 10 ROWS ONLY;
id title author year_published language
1 In Search of Lost Time Marcel Proust 1913 French
2 Ulysses James Joyce 1922 English
3 Don Quixote Miguel de Cervantes 1605 Spanish
4 Moby Dick Herman Melville 1851 English
6 War and Peace Leo Tolstoy 1869 Russian
7 The Odyssey Homer -700 Greek
8 The Great Gatsby F. Scott Fitzgerald 1925 English
9 The Divine Comedy Dante Alighieri 1472 Italian
10 Madame Bovary Gustave Flaubert 1857 French
11 The Brothers Karamazov Fyodor Dostoyevsky 1880 Russian
Điều quan trọng cần lưu ý ở đây là tập kết quả của chúng tôi hơi khác trong hai truy vấn trên. Trong phần đầu tiên, chúng tôi chỉ liệt kê 10
đầu tiên sách, nhưng trong INNER JOIN
truy vấn, chúng tôi chỉ trả về kết quả đáp ứng tất cả các điều kiện từ cả hai bảng. Vì lý do này, bản ghi của Hamlet
(có language_id
giá trị của null
hoặc trống) bị bỏ qua và không được trả lại trong kết quả INNER JOIN
của chúng tôi .
Tham gia bên ngoài là gì?
Thay vì chỉ trả về kết quả đáp ứng tất cả các điều kiện kết hợp của INNER JOIN
, một OUTER JOIN
không chỉ trả về kết quả thỏa mãn tất cả các điều kiện mà còn còn trả về các hàng từ một bảng không thỏa mãn điều kiện. Bảng được chọn cho việc “bỏ qua” các yêu cầu có điều kiện này được xác định theo hướng hoặc “cạnh” của phép nối, thường được gọi là LEFT
hoặc RIGHT
nối ngoài.
Khi xác định một bên cho OUTER JOIN
của bạn , bạn đang chỉ định bảng nào sẽ luôn trả về hàng của nó ngay cả khi đối lập bảng ở phía bên kia của phép nối bị thiếu hoặc null
các giá trị như một phần của điều kiện kết hợp.
Do đó, nếu chúng ta thực hiện cùng một JOIN
cơ bản như trên để truy xuất books
và language name
, chúng tôi biết rằng books
của chúng tôi bảng phải luôn trả về dữ liệu, vì vậy JOIN
của chúng tôi bên phải “hướng về phía” books
của chúng tôi bảng, do đó tạo ra các languages
bảng OUTER
bảng mà chúng tôi đang đính kèm với nó.
Để thực hiện điều này, chúng tôi chỉ cần thay đổi:
books b INNER JOIN library.languages l
… Đến đây:
books b LEFT OUTER JOIN library.languages l
Do đó, toàn bộ truy vấn và tập kết quả trông gần giống với INNER JOIN
ngoại trừ thay đổi nhỏ đó:
SELECT
b.id,
b.title,
b.author,
b.year_published,
l.name language
FROM
books b
LEFT OUTER JOIN
library.languages l
ON
b.language_id = l.id
ORDER BY
b.id
FETCH FIRST 10 ROWS ONLY;
id title author year_published language
1 In Search of Lost Time Marcel Proust 1913 French
2 Ulysses James Joyce 1922 English
3 Don Quixote Miguel de Cervantes 1605 Spanish
4 Moby Dick Herman Melville 1851 English
5 Hamlet William Shakespeare 1601 (null)
6 War and Peace Leo Tolstoy 1869 Russian
7 The Odyssey Homer -700 Greek
8 The Great Gatsby F. Scott Fitzgerald 1925 English
9 The Divine Comedy Dante Alighieri 1472 Italian
10 Madame Bovary Gustave Flaubert 1857 French
Như mong đợi, bằng cách sử dụng LEFT OUTER JOIN
thay vì INNER JOIN
trước đó , chúng tôi đang tận dụng tối đa cả hai thế giới:Chúng tôi không bỏ qua bất kỳ books
bản ghi (chẳng hạn như Hamlet
) đơn giản vì language_id
giá trị là null
cho bản ghi đó, nhưng cho tất cả các bản ghi mà language_id
tồn tại, chúng tôi nhận được language name
được định dạng độc đáo lấy từ languages
của chúng tôi bảng.
Thực hiện Tham gia Bên ngoài Sử dụng Biểu tượng (+)
Như đã chỉ ra trong tài liệu chính thức, Oracle cung cấp một toán tử kết hợp ngoài outer join operator
(+
ký hiệu) viết tắt để thực hiện OUTER JOINS
.
Trên thực tế, +
biểu tượng được đặt trực tiếp trong điều kiện và ở bên cạnh bảng tùy chọn (bảng được phép chứa trống hoặc null
giá trị trong điều kiện).
Do đó, chúng tôi có thể viết lại một lần nữa LEFT OUTER JOIN
ở trên của chúng tôi câu lệnh sử dụng +
toán tử như vậy:
SELECT
b.id,
b.title,
b.author,
b.year_published,
l.name language
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
ORDER BY
b.id
FETCH FIRST 10 ROWS ONLY;
Kết quả giống với LEFT OUTER JOIN
tiêu chuẩn ví dụ ở trên, vì vậy chúng tôi sẽ không đưa chúng vào đây. Tuy nhiên, có một khía cạnh quan trọng cần lưu ý về cú pháp sử dụng +
toán tử cho OUTER JOINS
.
+
nhà điều hành phải ở bên trái của điều kiện (bên trái của dấu bằng =
ký tên). Do đó, trong trường hợp này, vì chúng tôi muốn đảm bảo rằng languages
của chúng tôi table là bảng tùy chọn có thể trả về null
trong quá trình so sánh này, chúng tôi đã hoán đổi thứ tự của các bảng trong điều kiện này, vì vậy languages
ở bên trái (và là tùy chọn) trong khi books
ở bên phải.
Cuối cùng, do sự sắp xếp lại các cạnh của bảng trong điều kiện khi sử dụng +
, điều quan trọng là phải nhận ra rằng ở trên chỉ đơn giản là viết tắt của một RIGHT OUTER JOIN
. Điều này có nghĩa là đoạn mã này của truy vấn:
FROM
books b,
library.languages l
WHERE
l.id (+)= b.language_id
… Giống hệt với cái này:
FROM
library.languages l
RIGHT OUTER JOIN
books b
ON
b.language_id = l.id