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

Postgresql menghapus beberapa baris dari beberapa tabel

Mengatur penghapusan berjenjang yang tepat adalah bijaksana dan biasanya merupakan solusi yang tepat untuk ini. Untuk kasus khusus tertentu, ada solusi lain untuk ini yang mungkin relevan.

Jika Anda perlu melakukan beberapa penghapusan berdasarkan kumpulan data umum, Anda dapat menggunakan Ekspresi Tabel Umum (CTE) .

Sulit untuk membuat contoh sederhana karena kasus penggunaan utama untuk ini dapat ditutupi dengan penghapusan berjenjang.

Sebagai contoh kita akan menghapus semua item di tabel A yang nilainya ada di kumpulan nilai yang kita hapus dari tabel B. Biasanya ini adalah kunci, tetapi jika tidak, maka penghapusan berjenjang tidak dapat digunakan .

Untuk mengatasi ini, Anda menggunakan CTE

WITH Bdeletes AS (
    DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)

Contoh ini sengaja dibuat sederhana karena maksud saya bukan untuk memperdebatkan pemetaan kunci dll, tetapi untuk menunjukkan bagaimana dua atau lebih penghapusan dapat dilakukan dari kumpulan data bersama. Ini juga bisa jauh lebih rumit, termasuk perintah pembaruan, dll.

Berikut adalah contoh yang lebih kompleks (dari database pribadi Darth Vader). Dalam hal ini, kami memiliki tabel yang mereferensikan tabel alamat. Kita perlu menghapus alamat dari tabel alamat jika mereka ada dalam daftar planet yang dia hancurkan. Kami ingin menggunakan informasi ini untuk menghapus dari tabel orang, tetapi hanya jika mereka ada di planet (atau dalam daftar pembunuhan trofi)

with AddressesToDelete as (
    select AddressId from Addresses a 
    join PlanetsDestroyed pd on pd.PlanetName = a.PlanetName
),
PeopleDeleted as (
    delete from People 
    where AddressId in (select * from AddressesToDelete)
    and OffPlanet = false 
    and TrophyKill = false
    returning Id
),
PeopleMissed as (
    update People 
    set AddressId=null, dead=(OffPlanet=false)
    where AddressId in (select * from AddressesToDelete)
    returning id
)
Delete from Addresses where AddressId in (select * from AddressesToDelete)

Sekarang database-nya up to date. Tidak ada kegagalan integritas karena penghapusan Alamat. Perhatikan bahwa saat kami mengembalikan data dari pembaruan dan penghapusan pertama, itu tidak berarti kami harus menggunakannya. Saya tidak yakin apakah Anda dapat menghapus dalam CTE tanpa data yang dikembalikan (SQL saya mungkin juga salah dalam penggunaan pengembalian dari pembaruan - Saya tidak dapat menguji menjalankan ini karena Darth V. berada di suasana hati yang rewel.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menjalankan program Java dari baris perintah Linux yang membutuhkan file tambahan

  2. Tidak dapat memasukkan JSON dari PostgreSQL ke elasticsearch. Mendapatkan kesalahan - "Pengecualian saat menjalankan kueri JDBC"

  3. Postgresql &psycopg2:database tidak ada

  4. Bagaimana cara memeriksa apakah layanan yang saya tidak tahu namanya berjalan di Ubuntu

  5. Bagaimana cara menghitung setof/jumlah kunci JSON di postgresql?