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

Oracle đến PostgreSQL:Cú pháp nối ngoài ANSI trong PostgreSQL

Chúng tôi tìm thấy chính mình ở bài viết thứ ba trong loạt bài về việc di chuyển Oracle. Lần này, chúng ta xem xét những toán tử kỳ lạ sửa đổi tiêu chí mệnh đề WHERE trong Oracle (+). Giống như mọi thứ khác, PostgreSQL có một giải pháp cho điều đó.

THAM GIA PHẢI

Oracle hỗ trợ và nhiều nhà phát triển sử dụng cú pháp ANSI bên ngoài JOIN bằng cách sử dụng các toán tử cho mệnh đề điều kiện.

Thông thường, nó trông giống như sau:

SELECT *
FROM person, places
WHERE person.id = places.person_id(+)

Mục tiêu của cú pháp này là một phép nối bên ngoài bên phải. Theo thuật ngữ lý thuyết tập hợp, đây là tập hợp con bao gồm tất cả các địa điểm, bất kể người nào.

Kết quả của một mẫu nhỏ sẽ giống như sau:

id last_name first_name id vị trí person_id
1 (NULL) (NULL) 1 Dallas (NULL)
2 Roybal Kirk 2 Luân Đôn 2
3 Riggs Simon 3 Paris 3

Cú pháp này không được hỗ trợ trong PostgreSQL.

Để đạt được kết quả tương tự, bạn sẽ sử dụng cú pháp SQL tiêu chuẩn cho các phép nối bên ngoài.

SELECT *
FROM persons
RIGHT JOIN places
ON persons.id = places.person_id;

SQL cũng cung cấp một trạng từ làm rõ OUTER . Bộ làm rõ này là hoàn toàn tùy chọn, vì bất kỳ RIGHT JOIN nào theo định nghĩa là OUTER tham gia.

THAM GIA ĐẦY ĐỦ

Tương tự, việc sử dụng cú pháp Oracle cho một phép nối đầy đủ không hoạt động trong PostgreSQL.

SELECT *
FROM persons, places
WHERE persons.id(+) = places(+);

Mục tiêu của cú pháp này là một danh sách đầy đủ các người và các địa điểm cho dù một người có được liên kết với một địa điểm hay không.

Kết quả như sau:

id last_name first_name ** id vị trí person_id
1 (NULL) (NULL) 1 Dallas (NULL)
2 Roybal Kirk 2 Luân Đôn 2
3 Riggs Simon 3 Paris 3
4 Andrew Dunstan (NULL) (NULL) (NULL)

Sử dụng cú pháp PostgreSQL, truy vấn sẽ được viết như vậy:

SELECT *
FROM persons
FULL JOIN places
ON persons.id = places.person_id;

Một lần nữa, OUTER từ khóa là hoàn toàn tùy chọn.

CROSS JOIN

Một lợi thế khác biệt của phương pháp sử dụng từ khóa thay vì các mối quan hệ ngầm là bạn không thể vô tình tạo ra một sản phẩm chéo.

Cú pháp:

SELECT *
FROM persons
LEFT JOIN places;

Sẽ dẫn đến lỗi:

ERROR:  syntax error at or near ";"

Cho biết rằng câu lệnh chưa hoàn thành ở điểm đánh dấu kết thúc dòng “;”.

PostgreSQL sẽ tạo sản phẩm kết hợp chéo bằng cú pháp ANSI.

SELECT *
FROM persons, places;
id last_name first_name id vị trí person_id
1 Dunstan Andrew 1 Dallas (null)
1 Dunstan Andrew 2 Luân Đôn 2
1 Dunstan Andrew 3 Paris 3
1 Dunstan Andrew 4 Madrid (null)
2 Roybal Kirk 1 Dallas (null)
2 Roybal Kirk 2 Luân Đôn 2
2 Roybal Kirk 3 Paris 3
2 Roybal Kirk 4 Madrid (null)
3 Riggs Simon 1 Dallas (null)
3 Riggs Simon 2 Luân Đôn 2
3 Riggs Simon 3 Paris 3
3 Riggs Simon 4 Madrid (null)
6 Wong Đánh dấu 1 Dallas (null)
6 Wong Đánh dấu 2 Luân Đôn 2
6 Wong Đánh dấu 3 Paris 3
6 Wong Đánh dấu 4 Madrid (null)

Điều này có nhiều khả năng là lỗi mã hóa hơn là kết quả cố ý.

Để có được chức năng này một cách có chủ đích, bạn nên sử dụng CROSS JOIN tuyên bố.

SELECT *
FROM persons
CROSS JOIN places;

Do đó, làm cho nó rõ ràng những gì có nghĩa là trong tuyên bố.

THAM GIA TỰ NHIÊN

PostgreSQL hỗ trợ NATURAL JOIN cú pháp, nhưng hơi bị phản đối.

SELECT *
FROM persons
NATURAL JOIN places;

Điều này tạo ra kết quả sau.

id last_name first_name parent_id vị trí person_id
1 Dunstan Andrew (null) Dallas (null)
2 Roybal Kirk 1 Luân Đôn 2
3 Riggs Simon 1 Paris 3

Tuy nhiên, cú pháp này là một vấn đề. Ví dụ của chúng tôi, cột "id" trong cả hai bảng không liên quan gì đến nhau . Sự liên kết này đã tạo ra một kết quả, nhưng một kết quả có nội dung hoàn toàn không liên quan.

Ngoài ra, bạn có thể có một truy vấn ban đầu hiển thị kết quả chính xác, nhưng các câu lệnh DDL tiếp theo sẽ ảnh hưởng âm thầm.

Cân nhắc:

ALTER TABLE person ADD COLUMN places_id bigint;
ALTER TABLE places ADD COLUMN places_id bigint;
ALTER TABLE person ADD COLUMN person_id bigint;

Bây giờ cột gì là NATURAL JOIN sử dụng? Các lựa chọn là id, place_id, person_id và tất cả các lựa chọn ở trên. Tôi sẽ để câu trả lời như một bài tập cho người đọc.

Cú pháp này là một quả bom hẹn giờ cho mã của bạn. Chỉ cần không sử dụng nó.

Được rồi, vậy là bạn không bị thuyết phục. Chà, sau đó ít nhất cũng có một số quy ước mã hóa lành mạnh. Đối với bảng mẹ, hãy đặt tên cho cột nhận dạng là “myparenttable_id”. Khi tham chiếu nó từ các quan hệ con, hãy sử dụng cùng một tên, “myparenttable_id”. Không bao giờ đặt tên cho bất kỳ thứ gì là “id”, và không bao giờ tạo tham chiếu đến một cột có tên khác. À, quên nó đi. Đừng làm điều này.

Bạn có thể bị cám dỗ để phân biệt câu đố trước đó bằng cách sử dụng USING từ khóa. Nó sẽ trông như thế này:

SELECT *
FROM persons
JOIN places
USING (id);

Nhưng USING từ khóa chỉ có thể tận dụng các kết quả trùng khớp tên chính xác giữa các bảng. Một lần nữa, trong ví dụ của chúng tôi là sai lầm chết người.

Lựa chọn thực tiễn tốt nhất cho PostgreSQL là chỉ cần tránh thiết kế các bảng theo tiêu chuẩn quy ước mã hóa.

Tóm tắt

Các kỹ thuật từ khóa này (so với toán tử) cũng có sẵn trên Oracle. Chúng đa nền tảng hơn và ít mơ hồ hơn. Chỉ điều đó thôi cũng sẽ khiến chúng trở thành những phương pháp hay nhất.

Thêm vào đó, chúng để lộ các lỗi logic khi được sử dụng không đúng cách. Đối với bất kỳ sự phát triển nào trong PostgreSQL, chúng tôi đơn phương khuyên bạn nên sử dụng các từ khóa rõ ràng.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng pg_dump để chỉ nhận các câu lệnh chèn từ một bảng trong cơ sở dữ liệu

  2. lastInsertId không hoạt động trong Postgresql

  3. Django duy nhất cùng nhau ràng buộc thất bại?

  4. Sự phát triển của khả năng chịu lỗi trong PostgreSQL:Cam kết đồng bộ

  5. Thiết kế cơ sở dữ liệu tạm thời, có sự thay đổi (hàng trực tiếp so với hàng nháp)