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
FROM
có 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ởiFROM
trướ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ỳFROM
nào khác mục.)Các hàm bảng xuất hiện trong
FROM
cũ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ởiFROM
trong 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
FROM
mệ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
INNER
vàOUTER
cá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
,ON
join_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.