2013-06-14 32 views
7

Đây là một câu hỏi đã boggling tôi trong vài ngày nay, và tôi tìm kiếm và tìm kiếm nhưng không thể tìm thấy bất kỳ câu trả lời thuyết phục!2 Tham gia bên ngoài trên cùng một bảng?

Câu hỏi đơn giản, tại sao nó bị giới hạn có 2 lần tham gia bên ngoài trong SQL, trên cùng một bảng ngay cả với các cột khác nhau đang được sử dụng, hãy kiểm tra các truy vấn bên dưới để hiểu rõ hơn. Ngoài ra tôi có thể khắc phục chúng bằng cách sử dụng truy vấn con lồng nhau hoặc tham gia ANSI, nhưng sau đó tại sao nó thậm chí còn bị hạn chế ở nơi đầu tiên sử dụng toán tử (+)!

Trong câu hỏi này, tôi đề cập đến lỗi: "ORA-01.417: một bảng có thể bên ngoài tham gia vào nhiều nhất là một bảng khác"

Những gì tôi muốn hỏi là:

Tại sao điều này được phép:

select * from 
a, b, c 
where a.a1 = b.b1 
and a.a2 = c.c1 

Và tại sao điều này là không được phép:

select * from 
a, b, c 
where a.a1(+) = b.b1 
and a.a2(+) = c.c1 

Hãy để lại ANSI và lồng nhau subqueries mình

+6

Bạn có thể cung cấp ví dụ về những gì bạn đang cố gắng làm không? Bạn sẽ có thể tham gia ('bên trong' hoặc' bên ngoài') cùng một bảng nhiều lần nếu cần ... – sgeddes

+2

Như @sgeddes nói, bạn rất có thể bị lẫn lộn. Không có giới hạn "2 tham gia bên ngoài" trên Oracle – Lamak

+2

Bạn đang đề cập đến 'ORA-01417: một bảng có thể được nối ngoài với tối đa một bảng khác' không? –

Trả lời

10

Hạn chế được mô tả trong tài liệu của Oracle: Outer Joins

Oracle khuyến cáo rằng bạn sử dụng mệnh đề FROM OUTER JOIN Cú pháp chứ không phải là Oracle tham gia điều hành. Bên ngoài tham gia truy vấn sử dụng Oracle tham gia điều hành (+) phải tuân thủ các quy tắc sau đây và hạn chế, mà không áp dụng cho mệnh đề FROM OUTER JOIN Cú pháp:

...

Trong một truy vấn mà thực hiện các phép nối ngoài của nhiều hơn hai cặp bảng, một bảng đơn có thể là bảng được tạo ra không có giá trị cho chỉ một bảng khác. Vì lý do này, bạn không thể áp dụng toán tử (+) cho các cột của B trong điều kiện nối cho A và B và điều kiện nối cho B và C. Tham khảo SELECT để biết cú pháp cho phép nối ngoài.

mà về cơ bản có nghĩa là (được mô tả trong cú pháp ANSI/ISO) mà bạn không thể có với (+) cú pháp cũ những gì là hoàn toàn hợp lệ trong ANSI/ISO:

--- Query 1 --- 
    a 
RIGHT JOIN b 
    ON a.x = b.x 
RIGHT JOIN c 
    ON a.y = c.y 

hay:

--- Query 1b --- 
    c 
LEFT JOIN 
    b LEFT JOIN a 
     ON a.x = b.x 
    ON a.y = c.y 

Đó chỉ là một trong nhiều hạn chế của cú pháp cũ của Oracle.


Vì lý do hạn chế này, đó có thể là chi tiết triển khai hoặc/và sự mơ hồ của các lần tham gia đó. Trong khi hai gia nhập trên là 100% tương đương, sau đây là không tương đương với trên hai:

--- Query 2 --- 
    a 
RIGHT JOIN c 
    ON a.y = c.y 
RIGHT JOIN b 
    ON a.x = b.x 

Xem các thử nghiệm trong SQL-Fiddle. Vì vậy, câu hỏi đặt ra. Làm thế nào để tham gia độc quyền được giải thích, như truy vấn 1 hoặc 2?

FROM a, b, c 
WHERE a.y (+) = c.y 
    AND a.x (+) = b.x 

Không có giới hạn nếu một bảng xuất hiện ở phía bên trái của (2 trở lên) bên ngoài tham gia. Đây là hoàn toàn hợp lệ, ngay cả với cú pháp cũ:

FROM a 
    LEFT JOIN b ON a.x = b.x 
  LEFT JOIN c ON a.y = c.y 
    ... 
    LEFT JOIN z ON a.q = z.q 

FROM a, b, ..., z 
WHERE a.x = b.x (+) 
  AND a.y = c.y (+) 
    ... 
    AND a.q = z.q (+) 
+0

Giải thích hay. –

+0

Hạn chế này dường như đã được thoải mái trong 12c –

+0

@shonkylinuxuser Liên kết đến điều này? Tôi sẽ nghĩ rằng họ sẽ loại bỏ hỗ trợ cho cú pháp cũ, không tăng cường nó. –