PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm cách nào để loại bỏ các hàng trùng lặp với các phụ thuộc khóa ngoại?

Bạn có thể làm điều này hiệu quả hơn nhiều với một câu lệnh SQL duy nhất với CTE sửa đổi dữ liệu .

WITH plan AS (
   SELECT *
   FROM  (
      SELECT recid, min(recid) OVER (PARTITION BY cdesc) AS master_recid
      FROM   cpt
      ) sub
   WHERE  recid <> master_recid  -- ... <> self
   )
 , upd_lab AS (
   UPDATE lab l
   SET    cpt_recid = p.master_recid   -- link to master recid ...
   FROM   plan p
   WHERE  l.cpt_recid = p.recid
   )
DELETE FROM cpt c
USING  plan p
WHERE  c.recid = p.recid
RETURNING c.recid;

db <> fiddle tại đây (trang 11)
SQL Fiddle (trang 9.6)

Điều này phải nhiều nhanh hơn và sạch hơn. Việc tạo vòng lặp là tương đối đắt, việc xử lý ngoại lệ tương đối thậm chí còn đắt hơn.
Quan trọng hơn, các tham chiếu trong lab được chuyển hướng đến hàng chính tương ứng trong cpt tự động, chưa có trong mã gốc của bạn. Vì vậy, bạn có thể xóa tất cả các bản sao cùng một lúc .

Bạn vẫn có thể gói nó trong một hàm plpgsql hoặc SQL nếu bạn muốn.

Giải thích

  1. Trong gói CTE plan đầu tiên , xác định một hàng chính trong mỗi phân vùng với cùng một cdesc . Trong trường hợp của bạn, hàng có recid tối thiểu .

  2. Trong CTE thứ 2 upd_lab chuyển hướng tất cả các hàng tham chiếu bản dupe đến hàng chính trong cpt .

  3. Cuối cùng, xóa các lỗi sai, điều này sẽ không làm tăng ngoại lệ vì các hàng tùy thuộc được liên kết với hàng chính còn lại hầu như cùng một lúc.

ON DELETE RESTRICT

Tất cả các CTE và truy vấn chính của một câu lệnh hoạt động trên cùng một ảnh chụp nhanh của các bảng bên dưới, hầu như đồng thời . Họ không thấy tác dụng của nhau đối với các bảng bên dưới:

Người ta có thể mong đợi một ràng buộc FK với ON DELETE RESTRICT để nâng cao các ngoại lệ bởi vì, [theo tài liệu] [3]:

Tuy nhiên, câu lệnh trên là một lệnh đơn và, [hướng dẫn sử dụng lại] [3]:

Tôi nhấn mạnh đậm. Hoạt động với mặc định ít hạn chế hơn ON DELETE NO ACTION tất nhiên là quá.

Tuy nhiên, hãy cảnh giác với các giao dịch đồng thời ghi vào cùng một bảng, nhưng đó là sự cân nhắc chung, không cụ thể cho nhiệm vụ này.

Một ngoại lệ áp dụng cho UNIQUEPRIMARY KEY nhưng điều đó không liên quan đến điều này trường hợp:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tôi gặp lỗi pg khi cố gắng phá hủy bộ điều khiển

  2. Postgres LIKE với giá trị cột là chuỗi con

  3. Làm cách nào để tạo bản sao lưu của một bảng trong cơ sở dữ liệu postgres?

  4. CHÈN với tên bảng động trong chức năng kích hoạt

  5. Lỗi Rails + PostGIS khi di chuyển cơ sở dữ liệu