sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan fjerner du dublerede rækker med afhængigheder af fremmednøgler?

Du kan gøre dette meget mere effektivt med en enkelt SQL-sætning med datamodificerende CTE'er .

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 her (s. 11)
SQL Fiddle (s. 9.6)

Det burde være meget hurtigere og renere. Looping er forholdsvis dyrt, undtagelseshåndtering er forholdsvist endnu dyrere.
Vigtigere er referencer i lab omdirigeres til den respektive masterrække i cpt automatisk, hvilket endnu ikke var i din oprindelige kode. Så du kan slette alle duper på én gang .

Du kan stadig pakke dette ind i en plpgsql- eller SQL-funktion, hvis du vil.

Forklaring

  1. I den 1. CTE plan , identificer en masterrække i hver partition med den samme cdesc . I dit tilfælde rækken med minimum recid .

  2. I 2. CTE upd_lab omdiriger alle rækker, der refererer til en dupe, til masterrækken i cpt .

  3. Slet endelig duper, hvilket ikke vil give undtagelser, fordi afhængige rækker bliver linket til den resterende masterrække praktisk talt på samme tid.

ON DELETE RESTRICT

Alle CTE'er og hovedforespørgslen i en erklæring operere på det samme øjebliksbillede af underliggende tabeller, praktisk talt samtidigt . De ser ikke hinandens effekter på underliggende tabeller:

Man kunne forvente en FK-begrænsning med ON DELETE RESTRICT at rejse undtagelser, fordi [pr. dokumentation][3]:

Ovenstående erklæring er dog en enkelt kommando og [manualen igen][3]:

Fed fremhævelse min. Virker for den mindre restriktive standard ON DELETE NO ACTION også, selvfølgelig.

Men vær på vagt over for samtidige transaktioner, der skriver til de samme tabeller, men det er en generel betragtning, ikke specifik for denne opgave.

En undtagelse gælder for UNIQUE og PRIMARY KEY begrænsning, men det vedrører ikke dette sag:



  1. Indsættelse af nationale tegn i en orakel NCHAR eller NVARCHAR kolonne virker ikke

  2. Forårsaget af:org.postgresql.util.PSQLEundtagelse:FATAL:adgangskodegodkendelse mislykkedes for brugeradministrator

  3. Brug PDO database klasse uden at oprette ny forbindelse hver gang?

  4. SQL Server FOR XML Path laver gentagne noder