Giống như một truy vấn con tương quan
Tham LATERAL
gia (Postgres 9.3 trở lên) giống như một truy vấn con tương quan , không phải là truy vấn con đơn giản. Giống như Andomar đã chỉ ra , một hàm hoặc truy vấn con ở bên phải của phép LATERAL
nối phải được đánh giá một lần cho mỗi hàng bên trái của nó - giống như truy vấn con tương quan - trong khi truy vấn con đơn giản (biểu thức bảng) chỉ được đánh giá một lần . (Tuy nhiên, trình hoạch định 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 liên quan này có các ví dụ mã cho cả hai bên, giải quyết cùng một vấn đề:
Để trả về nhiều hơn một cột , việc 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 một truy vấn con tương quan là LEFT JOIN LATERAL ... ON true
:
Đọc hướng dẫn trên LATERAL
Nó có thẩm quyền hơn bất cứ điều gì chúng ta sẽ đưa vào câu trả lời ở đây:
Những điều mà một truy vấn phụ không thể làm
Có những điều mà một LATERAL
tham gia có thể làm, nhưng một (tương quan) subquery có thể không (dễ dàng). 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 nhiều hàng - ngoại trừ các lệnh gọi hàm trần (sẽ nhân các hàng kết quả nếu chúng trả về nhiều hàng). Nhưng ngay cả các hàm nhất định, các hàm trả về 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 cho phép trong FROM
điều khoản;
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 chức năng bảng.
Thông tin thêm về trường hợp đặc biệt của UNNEST( array_expression [, ... ] )
:
Các chức năng thiết lập trở lại trong SELECT
danh sách
Bạn cũng có thể sử dụng các hàm trả về như unnest()
trong SELECT
danh sách 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 cho đến Postgres 9.6. Nhưng cuối cùng nó đã được khử trùng bằng Postgres 10 và là một thay thế hợp lệ ngay bây giờ (ngay cả khi không phải là SQL tiêu chuẩn). Xem:
Xây dựng trên ví dụ trên:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
So sánh:
dbfiddle cho pg 9.6 tại đây
dbfiddle cho pg 10 tại đây
Làm rõ thông tin sai lệch
Hướng dẫn sử dụng:
Đối với các loại INNER
và OUTER
tham gia, một điều kiện tham gia phải được chỉ định, cụ thể là một trong số đó NATURAL
, ON
tham gia_condition hoặc USING
( tham gia [, ...]). Xem dưới đây cho ý nghĩa.
Đối với CROSS JOIN
, không có điều khoản nào có thể xuất hiện.
Vì vậy, hai truy vấn này là 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 @ Andomar của mã ví dụ là đúng (những CROSS JOIN
không đòi hỏi một điều kiện tham gia) và @ Attila là không hợp lệ.
apply
là giống nhưlateral
từ các tiêu chuẩn SQL)