Lebih mirip subquery yang berkorelasi
Sebuah LATERAL
bergabung (Postgres 9.3 atau yang lebih baru) lebih seperti subquery berkorelasi , bukan subquery polos. Seperti yang ditunjukkan Andomar , fungsi atau subquery di sebelah kanan LATERAL
join harus dievaluasi satu kali untuk setiap baris di sebelah kiri - sama seperti subquery yang dikorelasikan - sementara subquery polos (ekspresi tabel) dievaluasi sekali saja. (Perencana permintaan memiliki cara untuk mengoptimalkan kinerja untuk keduanya.)
Jawaban terkait ini memiliki contoh kode untuk kedua sisi, menyelesaikan masalah yang sama:
Untuk mengembalikan lebih dari satu kolom , LATERAL
gabungan biasanya lebih sederhana, lebih bersih, dan lebih cepat.
Juga, ingat bahwa padanan subquery yang berkorelasi adalah LEFT JOIN LATERAL ... ON true
:
Baca manual di LATERAL
Itu lebih berwibawa daripada apa pun yang akan kita jawab di sini:
Hal-hal yang tidak dapat dilakukan subquery
Ada hal - hal yang LATERAL
bisa dilakukan gabungan, tetapi subquery (berkorelasi) tidak bisa (dengan mudah). Subquery yang dikorelasikan hanya dapat mengembalikan nilai tunggal, bukan beberapa kolom dan bukan beberapa baris - dengan pengecualian panggilan fungsi kosong (yang mengalikan baris hasil jika menghasilkan banyak baris). Tetapi bahkan fungsi set-return tertentu hanya diperbolehkan dalam FROM
klausa. Suka unnest()
dengan banyak parameter di Postgres 9.4 atau lebih tinggi. Manual:
Ini hanya diperbolehkan dalam FROM
klausa;
Jadi ini berfungsi, tetapi tidak dapat dengan mudah diganti dengan subquery:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
Koma ( ,
) dalam FROM
klausa adalah notasi pendek untuk CROSS JOIN
.
LATERAL
diasumsikan secara otomatis untuk fungsi tabel.
Lebih lanjut tentang kasus khusus UNNEST( array_expression [, ... ] )
:
Atur fungsi pengembalian dalam SELECT
daftar
Anda juga dapat menggunakan fungsi set-return seperti unnest()
dalam SELECT
daftar secara langsung. Ini digunakan untuk memperlihatkan perilaku mengejutkan dengan lebih dari satu fungsi seperti itu dalam SELECT
daftar yang sama hingga Postgres 9.6. Tetapi akhirnya telah disanitasi dengan Postgres 10 dan merupakan alternatif yang valid sekarang (bahkan jika bukan SQL standar). Lihat:
Membangun contoh di atas:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Perbandingan:
dbfiddle untuk hal 9.6 di sini
dbfiddle untuk hal 10 di sini
Jelaskan informasi yang salah
Manual:
Untuk tipe INNER
dan OUTER
gabung, syarat bergabung harus ditentukan, yaitu tepat satu NATURAL
, ON
join_condition , atau USING
( join_column [, ...]). Lihat di bawah untuk maknanya.
Sebab CROSS JOIN
, tidak satu pun dari klausa ini dapat muncul.
Jadi dua pertanyaan ini valid (bahkan jika tidak terlalu berguna):
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;
Sementara yang ini tidak:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Itu sebabnya @ Andomar ini contoh kode benar (yang CROSS JOIN
tidak memerlukan kondisi join) dan @ Attila ini yaitu tidak sah.
apply
sama denganlateral
dari standar SQL)