2016-05-23 98 views
0

當試圖delete duplicates有:如何刪除具有重複值的特定列的行?

DELETE FROM staff 
WHERE staff_id NOT IN (SELECT MIN(staff_id) FROM staff GROUP BY store_id); 

有一個錯誤:

[23503] ERROR: update or delete on table "staff" violates foreign key constraint "payment_staff_id_fkey" on table "payment" Detail: Key (staff_id)=(3) is still referenced from table "payment".

事實上,支付有FK約束:

CREATE TABLE public.payment 
(
    payment_id integer NOT NULL DEFAULT nextval('payment_payment_id_seq'::regclass), 
    customer_id integer NOT NULL, 
    staff_id smallint NOT NULL, 
    rental_id integer NOT NULL, 
    amount numeric(5,2) NOT NULL, 
    payment_date timestamp without time zone NOT NULL, 
    CONSTRAINT payment_pkey PRIMARY KEY (payment_id), 
    CONSTRAINT payment_customer_id_fkey FOREIGN KEY (customer_id) 
     REFERENCES public.customer (customer_id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE RESTRICT, 
    CONSTRAINT payment_rental_id_fkey FOREIGN KEY (rental_id) 
     REFERENCES public.rental (rental_id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE SET NULL, 
    CONSTRAINT payment_staff_id_fkey FOREIGN KEY (staff_id) 
     REFERENCES public.staff (staff_id) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE RESTRICT 
) 
WITH (
    OIDS=FALSE 
); 

這是不可能的設置payment.staff_id = null因爲NOT NULL作爲suggested here

解決此問題的最簡單方法是什麼?

+1

'WHERE store_id NOT IN(SELECT MIN(staff_id)FROM staff GROUP BY store_id)'這看起來不太好,你正在比較store_ids和staff_ids。 – joop

+0

這意味着您嘗試刪除所有員工,每個商店除一名員工之外。非常不可能這是你真正想要的。 – joop

+0

這正是我需要刪除所有員工,除了每個商店的一名員工,因爲我在Hibernate中有@OneToOne映射,否則失敗。也許我應該修改一些約束條件到'ON DELETE CASCADE DEFERRABLE' ..... –

回答

3

看起來這是數據模型的問題,而不是數據庫。

此時限制嚴格禁止您執行此類刪除操作。看起來像嚴格規定「每筆付款都必須與工作人員聯繫,付款信息應保留在db」。因此,如果需要刪除職員記錄,則必須更改該規則。這裏有一些選擇:

  • 每筆款項確實有與誰與它和支付信息的工作應該留在DB工作人員聯繫起來。在這種情況下,你就必須做出staff_id可空,並改變約束ON DELETE SET NULL
  • 每筆付款確有與誰與它的工作 工作人員和支付信息被鏈接不一定應該留在DB 。如果你想刪除的刪除工作人員處理的款項,更改DELETE限制ON DELETE CASCADE
  • 每筆付款確有與誰與它的工作 一名工作人員被鏈接或另一個和支付信息應保持在db中。也許可以將支付重新引用給另一名工作人員,例如組織負責人。在這種情況下,您應該將約束更改爲ON DELETE SET DEFAULT(並設置默認值c)。
  • 另外一個選擇是通過將public.staff中的記錄標記爲檔案而不是刪除來保留職員id。如果是這樣,你需要一種方式來做到這一點:public.staff中的一些布爾列或類似的東西。

無論如何,它首先是業務邏輯問題,而不是技術問題。

編輯:這是要麼改變了問題,要麼我錯過了註釋「試圖刪除重複項」。如果是這樣,你只需要更新與東西成員鏈接的實體,以刪除引用它們到實際的實體,而不是刪除之前的重複。