Dữ liệu trong database nằm ở nhiều table khác nhau. Do đó khi muốn lấy các dữ liệu có quan hệ với nhau từ nhiều table, ta phải sử dụng các phép kết bảng (Join).

 

Natural join

 

Natural join thực hiện việc kết bảng dựa trên các column có cùng tên và kiểu dữ liệu ở 2 table.

 

Chẳng hạn table HR.Departments có cột location_id, table HR.Locations cũng có cột location_id. Khi ta tìm xem phòng ban nào nằm ở thành phố nào bằng việc kết 2 table trên, Oracle sẽ tự động kết nối 2 table dựa trên column giống nhau là location_id.

 

 

Mệnh đề WHERE dùng để giới hạn bớt dữ liệu ta cần lấy. 2 table chỉ được join lại ở phần data giống nhau, trong trường hợp này là phần location_id của những department_id từ 10 -> 60.

 

Tuy nhiên cách join này không rõ ràng lắm và thường không được sử dụng.

 

Equijoin (Simple join, Inner join)

 

Phép kết bằng cho phép chúng ta kết nối 2 table với tên column hay kiểu dữ liệu có thể giống nhau hoặc khác nhau.

 

Sử dụng mệnh đề JOIN … USING, ta có thể chỉ ra column dùng để kết nối 2 table. Lưu ý, phía sau USING chỉ sử dụng tên column, không có tên table.

 

 

Dùng mệnh đề JOIN … ON, ta có thể chỉ ra column dùng để kết nối 2 table rõ ràng hơn, nhất là trong trường hợp tên column trong 2 table khác nhau.

 

 

Nếu muốn kết tiếp các table liên quan, ta chỉ cần sử dụng tiếp các mệnh đề JOIN … ON. Việc kết table sẽ được thực hiện từ trái sang phải. 

 

 

Để việc join thuận tiện, cũng như phân biệt các column trong mệnh đề SELECT, ta nên sử dụng table alias, cũng như phải chỉ rõ column trùng tên ở mệnh đề SELECT là của table nào, nếu không sẽ gặp lỗi ORA-00918: column ambiguously defined. 

 

VD: với câu query trên, ta không chỉ định rõ location_id thuộc về table Locations

 

 

2 cách trên Oracle tuân theo chuẩn SQL:1999, ngoài ra Oracle còn hỗ trợ kết bảng theo cú pháp riêng của mình, bằng việc đưa điều kiện join xuống dưới mệnh đề WHERE, mệnh đề FROM chỉ cần liệt kê tên table

 

 

Self join

 

Có 1 số trường hợp nội dung liên quan nằm giữa các column trong table, khi đó phải kết 1 table với chính nó để tìm ra thông tin liên quan. 

 

Trong table Employees, 1 người có thể là manager của người khác nếu employee_id của người đó nằm ở cột manager_id của người khác. Như vậy, ta join Employees với chính Employees dựa trên 2 column employee_id và manager_id

 

 

Viết theo cú pháp Oracle

 

 

Nonequijoin

 

Equijoin kết nối 2 table dựa trên các giá trị bằng nhau. Trường hợp ta kết nối 2 table không phải dựa trên các giá trị bằng nhau, ta gọi là Nonequijoin.

 

VD: ta có table Job_grades phân loại bậc lương, với nội dung như sau

 

 

Muốn kiểm tra bậc lương của 1 nhân viên, ta phải sử dụng Nonequijoin, do lương của nhân viên sẽ nằm trong khoảng [lowest_sal – highest_sal], chứ không bằng 1 giá trị chính xác

 

 

Viết theo cú pháp Oracle

 

 

Outer join

 

Equijoin hay Inner join trả về kết quả là những dòng thỏa mãn điều kiện join. Những dòng không thỏa mãn điều kiện sẽ không có trong kết quả. Trong trường hợp ta muốn lấy luôn các dòng không thỏa điều kiện, có thể sử dụng Outer join.

Có 3 loại outer join

  • Left outer join: lấy kết quả inner join và lấy luôn những dòng còn lại của table bên trái
  • Right outer join: lấy kết quả inner join và lấy luôn những dòng còn lại của table bên phải
  • Full outer join: lấy kết quả inner join và lấy luôn những dòng còn lại của cả 2 table

 

Minh họa Inner join và Outer join

Minh họa Inner join và Outer join

 

VD: inner join bình thường chỉ trả về kết quả thông tin nhân viên Grant nếu có department_id

 

 

Sử dụng Left outer join trả về cả thông tin của nhân viên Grant không có department_id

 

 

Viết theo cú pháp Oracle

 

 

VD: sử dụng Right outer join, lấy danh sách nhân viên các phòng ban từ 110 -> 140. Sẽ có phòng ban không có nhân viên xuất hiện.

 

 

Viết theo cú pháp Oracle

 

 

VD: sử dụng Full outer join

 

 

Oracle không hỗ trợ cú pháp riêng cho Full outer join.

 

Cross join

 

Hay còn gọi là tích Descartes, là việc join 2 table khi không có điều kiện, dẫn đến việc tạo ra kết quả rất lớn khi mỗi 1 dòng của table này join với tất cả các dòng của table kia (AxB). Kết quả thường không có giá trị, thường dùng khi ta muốn tạo 1 số lượng lớn data để test chẳng hạn.