Lebih mirip subquery yang berkorelasi
Sebuah LATERALbergabung (Postgres 9.3 atau yang lebih baru) lebih seperti subquery berkorelasi , bukan subquery polos. Seperti yang ditunjukkan Andomar , fungsi atau subquery di sebelah kanan LATERALjoin 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 , LATERALgabungan 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 LATERALbisa 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 FROMklausa. Suka unnest()dengan banyak parameter di Postgres 9.4 atau lebih tinggi. Manual:
Ini hanya diperbolehkan dalam FROMklausa;
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 FROMklausa adalah notasi pendek untuk CROSS JOIN.
LATERALdiasumsikan secara otomatis untuk fungsi tabel.
Lebih lanjut tentang kasus khusus UNNEST( array_expression [, ... ] ):
Atur fungsi pengembalian dalam SELECTdaftar
Anda juga dapat menggunakan fungsi set-return seperti unnest()dalam SELECTdaftar secara langsung. Ini digunakan untuk memperlihatkan perilaku mengejutkan dengan lebih dari satu fungsi seperti itu dalam SELECTdaftar 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 INNERdan OUTERgabung, 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 JOINtidak memerlukan kondisi join) dan @ Attila ini yaitu tidak sah.
applysama denganlateraldari standar SQL)