là gì một LATERAL tham gia?
Tính năng này đã được giới thiệu với PostgreSQL 9.3. Hướng dẫn sử dụng:
Truy vấn con xuất hiện trong
FROMcó thể được đặt trước từ khóaLATERAL. Điều này cho phép họ tham chiếu đến các cột được cung cấp bởiFROMtrước mặt hàng. (Không cóLATERAL, mỗi truy vấn con được đánh giá độc lập và do đó không thể tham chiếu chéo bất kỳFROMnào khác mục.)Các hàm bảng xuất hiện trong
FROMcũng có thể được đặt trước từ khóaLATERAL, nhưng đối với các chức năng, từ khóa là tùy chọn; các đối số của hàm có thể chứa các tham chiếu đến các cột được cung cấp bởiFROMtrong mọi trường hợp.
Các ví dụ mã cơ bản được cung cấp ở đó.
Giống như một tương quan truy vấn con
A LATERAL tham gia giống như một truy vấn con tương quan, không phải là một truy vấn con thuần túy, trong các biểu thức ở bên phải của một LATERAL tham gia được đánh giá một lần cho mỗi hàng bên trái của nó - giống như một tương quan truy vấn con - trong khi truy vấn con thuần túy (biểu thức bảng) được đánh giá một lần chỉ còn. (Tuy nhiên, công cụ lập kế hoạch truy vấn có các cách để tối ưu hóa hiệu suất cho cả hai.)
Câu trả lời có liên quan với các ví dụ mã cho cả hai cạnh nhau, giải quyết cùng một vấn đề:
- Tối ưu hóa truy vấn GROUP BY để truy xuất hàng mới nhất cho mỗi người dùng
Để trả về nhiều hơn một cột , một LATERAL tham gia thường đơn giản hơn, sạch hơn và nhanh hơn.
Ngoài ra, hãy nhớ rằng tương đương với truy vấn con tương quan là LEFT JOIN LATERAL ... ON true :
- Gọi một hàm trả về tập hợp với một đối số mảng nhiều lần
Những điều mà một truy vấn con không thể thực hiện
Có có những thứ mà một LATERAL tham gia có thể làm được, nhưng một truy vấn con (tương quan) không thể (dễ dàng). Một truy vấn con tương quan chỉ có thể trả về một giá trị duy nhất, không phải nhiều cột và không phải nhiều hàng - ngoại trừ các lệnh gọi hàm trống (nhân các hàng kết quả nếu chúng trả về nhiều hàng). Nhưng ngay cả một số hàm trả về tập hợp nhất định cũng chỉ được phép trong FROM mệnh đề. Giống như unnest() với nhiều tham số trong Postgres 9.4 trở lên. Hướng dẫn sử dụng:
Điều này chỉ được phép trong
FROMmệnh đề;
Vì vậy, điều này hoạt động, nhưng không thể (dễ dàng) được thay thế bằng một truy vấn con:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
Dấu phẩy (, ) trong FROM mệnh đề là ký hiệu ngắn cho CROSS JOIN .
LATERAL được giả định tự động cho các hàm của bảng.
Giới thiệu về trường hợp đặc biệt của UNNEST( array_expression [, ... ] ) :
- Làm cách nào để bạn khai báo một hàm set-return chỉ được phép trong mệnh đề FROM?
Đặt các hàm trả về trong SELECT danh sách
Bạn cũng có thể sử dụng các hàm trả về thiết lập như unnest() trong SELECT liệt kê trực tiếp. Điều này được sử dụng để thể hiện hành vi đáng ngạc nhiên với nhiều hơn một chức năng như vậy trong cùng một SELECT danh sách lên đến Postgres 9.6. Nhưng cuối cùng nó đã được làm sạch bằng Postgres 10 và là một giải pháp thay thế hợp lệ ngay bây giờ (ngay cả khi không phải là SQL tiêu chuẩn). Xem:
- Hành vi mong đợi cho nhiều hàm trả về trong mệnh đề SELECT là gì?
Xây dựng dựa trên ví dụ trên:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
So sánh:
dbfiddle cho trang 9.6 tại đây
dbfiddle cho trang 10 tại đây
Làm rõ thông tin sai lệch
Hướng dẫn sử dụng:
Đối với
INNERvàOUTERcác loại kết hợp, điều kiện kết hợp phải được chỉ định cụ thể, cụ thể là chính xác một trongNATURAL,ONjoin_condition hoặcUSING( join_column [, ...]). Xem bên dưới để biết ý nghĩa.
Đối vớiCROSS JOIN, không có mệnh đề nào trong số này có thể xuất hiện.
Vì vậy, hai truy vấn này hợp lệ (ngay cả khi không đặc biệt hữu ích):
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t ON TRUE;
SELECT *
FROM tbl t, LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Trong khi cái này thì không:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Đó là lý do tại sao ví dụ mã của Andomar là đúng (CROSS JOIN không yêu cầu điều kiện tham gia) và của Attila là không.