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

Apakah kueri jenis SELECT satu-satunya jenis yang dapat disarangkan?

Jawaban dasar

Ada CTE (Ekspresi Tabel Umum) di Postgres (seperti di RDBMS modern utama apa pun kecuali MySQL). Sejak versi 9.1 yang menyertakan CTE pengubah data. Itu bisa "bersarang".
Update:MySQL 8.0 akhirnya menambahkan CTE.

Tidak seperti subkueri CTEs berpose sebagai hambatan optimasi. Perencana kueri tidak dapat memasukkan perintah sepele ke dalam perintah utama atau menyusun ulang gabungan di antara kueri utama dan CTE. Hal yang sama dimungkinkan dengan subquery. Mungkin (sangat) baik atau (sangat) buruk untuk kinerja, itu tergantung.
Bagaimanapun, CTE memerlukan sedikit lebih banyak overhead (biaya kinerja) daripada subquery.
Pembaruan:Postgres 12 akhirnya dapat membuat CTE biasa inline dalam kueri utama.

Detail yang tidak Anda minta

Pertanyaan Anda sangat mendasar, hal di atas mungkin sudah cukup untuk menjawabnya. Tapi saya akan menambahkan sedikit untuk pengguna tingkat lanjut (dan contoh kode untuk menunjukkan sintaks).

Semua CTE kueri didasarkan pada snapshot yang sama dari database. CTE berikutnya dapat menggunakan kembali output dari CTE sebelumnya (tabel sementara internal), tetapi efek pada tabel yang mendasarinya tidak terlihat untuk CTE lainnya. Urutan beberapa CTE adalah arbitrer kecuali sesuatu dikembalikan dengan RETURNING klausa untuk INSERT , UPDATE , DELETE - tidak relevan untuk SELECT , karena tidak mengubah apa pun dan hanya membaca dari cuplikan.

Itu dapat memiliki efek halus dengan beberapa pembaruan yang akan memengaruhi baris yang sama. Hanya satu pembaruan dapat memengaruhi setiap baris. Manakah yang dipengaruhi oleh urutan CTE.

Coba prediksi hasilnya:

CREATE TEMP TABLE t (t_id int, txt text);
INSERT INTO t VALUES (1, 'foo'), (2, 'bar'), (3, 'baz');

WITH sel AS (SELECT * FROM t)
   , up1 AS (UPDATE t SET txt = txt || '1' WHERE t_id = 1 RETURNING *)
   , up2 AS (UPDATE t SET txt = t.txt || '2'
             FROM   up1
             WHERE  up1.t_id = t.t_id
             RETURNING t.*)
   , ins AS (INSERT INTO t VALUES (4, 'bamm'))
   , up3 AS (UPDATE t SET txt = txt || '3' RETURNING *)
SELECT 'sel' AS source, * FROM sel
UNION ALL
SELECT 'up1' AS source, * FROM up1
UNION ALL
SELECT 'up2' AS source, * FROM up2
UNION ALL
SELECT 'up3' AS source, * FROM up3
UNION ALL
SELECT 't'   AS source, * FROM t;

SQL Fiddle

Jangan kecewa, saya ragu ada banyak orang di sini yang bisa melakukannya. :)
Intinya:hindari perintah yang bertentangan di CTE.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Menghitung Persentil di PostgreSQL

  2. LEAST() Fungsi di PostgreSQL

  3. Bagaimana cara mencoba beberapa SELECT hingga hasilnya tersedia?

  4. Daftar Python ke Array PostgreSQL

  5. Bekerja menuju Postgres-XL 9.5