Giống như một truy vấn con tương quan
Tham LATERALgia (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 LATERALnố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 LATERALtham 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 LATERALtham 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 FROMmệ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 FROMmệ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 SELECTdanh 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 SELECTdanh 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 INNERvà OUTERtham 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 JOINkhông đòi hỏi một điều kiện tham gia) và @ Attila là không hợp lệ.
applylà giống nhưlateraltừ các tiêu chuẩn SQL)