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

tự tham gia và tham gia bên trong

Tôi thấy hữu ích khi coi tất cả các bảng trong câu lệnh SELECT là đại diện cho các tập dữ liệu của riêng chúng.

Trước khi áp dụng bất kỳ điều kiện nào, bạn có thể coi mỗi tập dữ liệu là hoàn chỉnh (ví dụ:toàn bộ bảng).

Kết hợp chỉ là một trong số các cách để bắt đầu tinh chỉnh các tập dữ liệu đó để tìm thông tin bạn thực sự muốn.

Mặc dù một lược đồ cơ sở dữ liệu có thể được thiết kế với một số mối quan hệ nhất định (Khóa chính <-> Khóa ngoại) nhưng những mối quan hệ này thực sự chỉ tồn tại trong ngữ cảnh của một truy vấn cụ thể. Người viết truy vấn có thể liên hệ bất cứ thứ gì họ muốn với bất cứ thứ gì họ muốn. Tôi sẽ đưa ra một ví dụ về điều này sau ...

INNER JOIN liên quan hai bảng với nhau. Thường có nhiều hoạt động JOIN trong một truy vấn để xâu chuỗi nhiều bảng lại với nhau. Nó có thể trở nên phức tạp như nó cần. Để có một ví dụ đơn giản, hãy xem xét ba bảng sau ...

STUDENT

| STUDENTID | LASTNAME | FIRSTNAME |
------------------------------------
      1     |  Smith   |   John
      2     |  Patel   |  Sanjay
      3     |   Lee    |  Kevin
      4     |  Jackson |  Steven
ENROLLMENT

| ENROLLMENT ID | STUDENTID | CLASSID |
---------------------------------------
        1       |     2     |    3
        2       |     3     |    1
        3       |     4     |    2
CLASS

| CLASSID | COURSE | PROFESSOR |
--------------------------------
     1    | CS 101 |   Smith
     2    | CS 201 |  Ghandi
     3    | CS 301 |  McDavid
     4    | CS 401 |  Martinez

Bảng SINH VIÊN và bảng LỚP được thiết kế để liên hệ với nhau thông qua bảng ĐĂNG KÝ. Loại bảng này được gọi là Bảng nối .

Để viết một truy vấn để hiển thị tất cả sinh viên và các lớp học mà họ đã đăng ký, một người sẽ sử dụng hai tham gia bên trong ...

SELECT stud.LASTNAME, stud.FIRSTNAME, class.COURSE, class.PROFESSOR
FROM STUDENT stud
INNER JOIN ENROLLMENT enr
    ON stud.STUDENTID = enr.STUDENTID
INNER JOIN CLASS class
    ON class.CLASSID = enr.CLASSID;

Đọc kỹ phần trên và bạn sẽ thấy điều gì đang xảy ra. Đổi lại những gì bạn sẽ nhận được là tập dữ liệu sau ...

 | LASTNAME | FIRSTNAME | COURSE | PROFESSOR |
 ---------------------------------------------
     Patel  |   Sanjay  | CS 301 |  McDavid
      Lee   |   Kevin   | CS 101 |   Smith
    Jackson |  Steven   | CS 201 |  Ghandi

Sử dụng mệnh đề JOIN, chúng tôi đã giới hạn các tập dữ liệu của cả ba bảng thành chỉ những tập phù hợp với nhau. "Kết quả phù hợp" được xác định bằng cách sử dụng nút BẬT điều khoản. Lưu ý rằng nếu bạn chạy truy vấn này, bạn sẽ không xem hàng CLASSID 4 từ bảng CLASS hoặc hàng STUDENTID 1 từ bảng STUDENT vì các ID đó không tồn tại trong các kết quả phù hợp (trong trường hợp này là bảng GHI DANH). Hãy xem các THAM GIA "LEFT" / "RIGHT" / "FULL OUTER" để đọc thêm về cách làm cho hoạt động đó khác đi một chút.

Xin lưu ý, theo nhận xét của tôi về "mối quan hệ" trước đó, không có lý do gì tại sao bạn không thể chạy một truy vấn liên quan đến bảng STUDENT và bảng CLASS trực tiếp trên các cột LASTNAME và PROFESSOR. Hai cột đó khớp nhau về kiểu dữ liệu và, hãy nhìn vào điều đó! Họ thậm chí có một giá trị chung! Đây có thể là một tập dữ liệu kỳ lạ để đổi lại. Quan điểm của tôi là nó có thể được thực hiện và bạn không bao giờ biết mình có thể có những nhu cầu gì trong tương lai đối với các kết nối thú vị trong dữ liệu của bạn. Hiểu thiết kế của cơ sở dữ liệu nhưng đừng coi "các mối quan hệ" là các quy tắc không thể bỏ qua.

Trong khi chờ đợi ... HÃY TỰ THAM GIA!

Xem xét bảng sau ...

PERSON

| PERSONID | FAMILYID |  NAME  |
--------------------------------
      1    |     1    |  John
      2    |     1    | Brynn
      3    |     2    | Arpan
      4    |     2    | Steve
      5    |     2    |  Tim
      6    |     3    | Becca

Nếu bạn cảm thấy muốn tạo một cơ sở dữ liệu về tất cả những người bạn biết và những người trong cùng một gia đình, điều này có thể trông như thế nào.

Nếu bạn muốn trả lại một người, ví dụ:PERSONID 4, bạn sẽ viết ...

SELECT * FROM PERSON WHERE PERSONID = 4;

Bạn sẽ biết rằng anh ấy đang ở trong gia đình với FAMILYID 2. Sau đó, để tìm tất cả của những NGƯỜI trong gia đình anh ấy mà bạn sẽ viết ...

SELECT * FROM PERSON WHERE FAMILYID = 2;

Ngay và luôn! Tất nhiên, SQL có thể thực hiện điều này trong một truy vấn bằng cách sử dụng, bạn đoán nó, TỰ THAM GIA.

Điều gì thực sự kích thích nhu cầu TỰ THAM GIA ở đây là bảng chứa một cột duy nhất (PERSONID) và một cột đóng vai trò là loại "Danh mục" (FAMILYID). Khái niệm này được gọi là Cardinality và trong trường hợp này đại diện cho một đến nhiều hoặc 1:M mối quan hệ. Chỉ có một của mỗi PERSON nhưng có nhiều CÁ NHÂN trong GIA ĐÌNH .

Vì vậy, những gì chúng tôi muốn trả lại là tất cả của các thành viên trong một gia đình nếu một thành viên của PERSONID của gia đình được biết ...

SELECT fam.*
FROM PERSON per
JOIN PERSON fam
    ON per.FamilyID = fam.FamilyID
WHERE per.PERSONID = 4;

Đây là những gì bạn sẽ nhận được ...

| PERSONID | FAMILYID |  NAME  |
--------------------------------
      3    |     2    | Arpan
      4    |     2    | Steve
      5    |     2    |  Tim

Hãy lưu ý một số điều. Các từ TỰ THAM GIA không xảy ra ở bất cứ đâu. Đó là vì TỰ THAM GIA chỉ là một khái niệm. Từ THAM GIA trong truy vấn ở trên có thể là THAM GIA TRÁI thay vào đó và những điều khác sẽ xảy ra. Điểm của TỰ THAM GIA là bạn đang sử dụng cùng một bảng hai lần.

Hãy xem xét hộp xà phòng của tôi từ trước trên các bộ dữ liệu. Ở đây chúng ta đã bắt đầu với tập dữ liệu từ bảng PERSON hai lần. Cả bản sao của tập dữ liệu ảnh hưởng đến tập dữ liệu khác trừ khi chúng tôi nói điều đó.

Hãy bắt đầu ở cuối truy vấn. per tập dữ liệu đang bị giới hạn chỉ ở những hàng có PERSONID =4. Biết bảng, chúng ta biết rằng sẽ trả về chính xác một hàng. Cột FAMILYID trong hàng đó có giá trị là 2.

Trong điều khoản BẬT, chúng tôi đang giới hạn fam tập dữ liệu (tại thời điểm này vẫn là toàn bộ bảng PERSON) chỉ những hàng mà giá trị của FAMILYID khớp với một hoặc nhiều trong số FAMILYID của per tập dữ liệu. Như chúng ta đã thảo luận, chúng ta biết per tập dữ liệu chỉ có một hàng, do đó một giá trị FAMILYID. Do đó, fam tập dữ liệu hiện chỉ chứa các hàng có FAMILYID =2.

Cuối cùng, ở đầu truy vấn, chúng tôi đang CHỌN tất cả các hàng trong fam tập dữ liệu.

Thì đấy! Hai truy vấn trong một.

Tóm lại, một INNER JOIN là một trong một số loại hoạt động JOIN. Tôi sẽ mạnh mẽ đề nghị đọc thêm về LEFT, RIGHT và FULL OUTER JOIN (gọi chung là OUTER JOINs ). Cá nhân tôi đã bỏ lỡ một cơ hội việc làm vì kiến ​​thức yếu về OUTER JOINs một lần và sẽ không để nó xảy ra lần nữa!

Đ TỰ THAM GIA chỉ đơn giản là bất kỳ hoạt động THAM GIA nào mà bạn đang liên kết một bảng với chính nó. Cách bạn chọn THAM GIA bảng đó với chính nó có thể sử dụng THAM GIA BÊN TRONG hoặc THAM GIA NGOÀI TRỜI. Lưu ý rằng với TỰ THAM GIA , để không gây nhầm lẫn cho công cụ SQL của bạn, bạn phải sử dụng bí danh bảng (fam và per từ trên. Tạo bất kỳ điều gì phù hợp với truy vấn của bạn) hoặc không có cách nào để phân biệt các phiên bản khác nhau của cùng một bảng.

Bây giờ bạn đã hiểu sự khác biệt, hãy mở rộng tâm trí của bạn và nhận ra rằng một truy vấn duy nhất có thể chứa tất cả các loại THAM GIA khác nhau cùng một lúc. Vấn đề chỉ là bạn muốn dữ liệu nào và bạn phải xoay và bẻ cong truy vấn của mình như thế nào để có được dữ liệu đó. Nếu bạn thấy mình đang chạy một truy vấn và lấy kết quả của truy vấn đó và sử dụng nó làm đầu vào của một truy vấn khác thì bạn có thể sử dụng JOIN để đặt nó thành một truy vấn thay thế.

Để chơi với SQL, hãy thử truy cập W3Schools.com Có một cơ sở dữ liệu được lưu trữ cục bộ ở đó với một loạt các bảng được thiết kế để liên kết với nhau theo nhiều cách khác nhau và nó chứa đầy dữ liệu! Bạn có thể TẠO, XÓA, CHÈN, CẬP NHẬT và CHỌN tất cả những gì bạn muốn và đưa cơ sở dữ liệu trở về mặc định bất kỳ lúc nào. Hãy thử tất cả các loại SQL để thử nghiệm các thủ thuật khác nhau. Tôi đã học được rất nhiều điều ở đó, bản thân tôi.

Xin lỗi nếu điều này hơi dài dòng nhưng cá nhân tôi đã phải vật lộn với khái niệm JOIN khi bắt đầu học SQL và giải thích một khái niệm bằng cách sử dụng một loạt các khái niệm phức tạp khác khiến tôi sa lầy. Tốt nhất thỉnh thoảng nên bắt đầu ở phần dưới cùng.

Tôi hy vọng nó sẽ giúp. Nếu bạn có thể đặt các THAM GIA vào túi sau của mình, bạn có thể làm việc kỳ diệu với SQL!

Chúc bạn truy vấn vui vẻ!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Liệt kê tất cả các trình kích hoạt trong Cơ sở dữ liệu Oracle

  2. SQL:Có thể SUM () các trường kiểu INTERVAL không?

  3. Chuỗi kết nối JDBC Thin trong Oracle sử dụng cả dấu hai chấm và dấu gạch chéo lên

  4. Cách phát hiện ký tự UTF8 4byte trong Oracle

  5. Cách sử dụng SYS_REFCURSUR được chọn để cập nhật trong pl / sql