PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Apa perbedaan antara LATERAL JOIN dan subquery di PostgreSQL?

Apa itu sebuah LATERAL bergabung?

Fitur ini diperkenalkan dengan PostgreSQL 9.3. Panduan:

Subquery muncul di FROM bisa didahului dengan kata kunciLATERAL . Ini memungkinkan mereka untuk mereferensikan kolom yang disediakan oleh FROM sebelumnya item. (Tanpa LATERAL , setiap subkueri dievaluasi secara independen sehingga tidak dapat melakukan referensi silang FROM other lainnya barang.)

Fungsi tabel muncul di FROM bisa juga didahului dengan kata kunci LATERAL , tetapi untuk fungsi kata kuncinya opsional; argumen fungsi dapat berisi referensi ke kolom yang disediakan dengan mendahului FROM item dalam hal apa pun.

Contoh kode dasar diberikan di sana.

Lebih seperti berkorelasi subkueri

Sebuah LATERAL join lebih seperti subquery yang berkorelasi, bukan subquery biasa, dalam ekspresi di sebelah kanan LATERAL join dievaluasi sekali untuk setiap baris di sebelah kirinya - seperti berkorelasi subquery - sementara subquery biasa (ekspresi tabel) dievaluasi sekali hanya. (Perencana kueri memiliki cara untuk mengoptimalkan kinerja keduanya.)
Jawaban terkait dengan contoh kode untuk keduanya secara berdampingan, memecahkan masalah yang sama:

  • Optimalkan kueri GROUP BY untuk mengambil baris terbaru per pengguna

Untuk mengembalikan lebih dari satu kolom , sebuah LATERAL join biasanya lebih sederhana, lebih bersih, dan lebih cepat.
Selain itu, ingat bahwa padanan dari subquery yang berkorelasi adalah LEFT JOIN LATERAL ... ON true :

  • Memanggil fungsi pengembalian-set dengan argumen array beberapa kali

Hal-hal yang tidak dapat dilakukan oleh subkueri

ada hal-hal yang LATERAL join dapat dilakukan, tetapi subquery (berkorelasi) tidak dapat (dengan mudah). Subquery yang berkorelasi hanya dapat mengembalikan satu nilai, bukan beberapa kolom dan bukan beberapa baris - dengan pengecualian panggilan fungsi kosong (yang mengalikan baris hasil jika mereka mengembalikan beberapa baris). Tetapi bahkan fungsi pengembalian set tertentu hanya diperbolehkan di FROM ayat. Seperti unnest() dengan beberapa parameter di Postgres 9.4 atau lebih baru. Panduan:

Ini hanya diperbolehkan di 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 (, ) di FROM klausa adalah notasi singkat untuk CROSS JOIN .
LATERAL diasumsikan secara otomatis untuk fungsi tabel.
Tentang kasus khusus UNNEST( array_expression [, ... ] ) :

  • Bagaimana Anda mendeklarasikan fungsi set-returning hanya diperbolehkan dalam klausa FROM?

Mengatur fungsi pengembalian dalam SELECT daftar

Anda juga dapat menggunakan fungsi pengembalian set seperti unnest() di SELECT daftar langsung. Ini digunakan untuk menunjukkan perilaku mengejutkan dengan lebih dari satu fungsi seperti itu dalam SELECT . yang sama daftar hingga Postgres 9.6. Tetapi akhirnya telah dibersihkan dengan Postgres 10 dan merupakan alternatif yang valid sekarang (bahkan jika bukan SQL standar). Lihat:

  • Apa perilaku yang diharapkan untuk beberapa fungsi pengembalian-set dalam klausa SELECT?

Berdasarkan 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

Klarifikasi informasi yang salah

Panduan:

Untuk INNER dan OUTER tipe join, kondisi join harus ditentukan, yaitu tepat satu dari NATURAL , ON join_condition ,atau USING (join_column [, ...]). Lihat di bawah untuk artinya.
Untuk CROSS JOIN , tidak satu pun dari klausa ini dapat muncul.

Jadi kedua kueri ini valid (walaupun 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 contoh kode Andomar benar (CROSS JOIN tidak memerlukan kondisi bergabung) dan is At Attila tidak.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Heroku pg:tarik gagal mengisi skema

  2. Cara menyisipkan secara massal hanya baris baru di PostreSQL

  3. GALAT:tidak dapat mengakses file “$libdir/plpython2” – ERROR:tidak dapat mengakses file “$libdir/plpython3”

  4. Cara Membatasi Akses ke Database di PostgreSQL

  5. Lokasi default database PostgreSQL di Linux