ELIMINA righe a cui non si fa riferimento in altre tabelle


15

Ho due tabelle in un database PostgreSQL 9.3: La tabella link_replyha una chiave esterna denominata che which_grouppunta alla tabella link_group.

Voglio eliminare tutte le righe da link_groupcui non link_replyesiste alcuna riga correlata . Sembra abbastanza semplice ma ho avuto delle difficoltà.

Sarà qualcosa di semplice come questo (non funzionante)?

DELETE FROM link_group WHERE link_reply = NULL;

hai un DDL che tutti possono vedere?
dizzystar,

Dai un'occhiata all'operatore MINUS. Devi specificare un campo in links_reply.
Vérace,

DELETE FROM links_group USING links_group AS lg LEFT JOIN links_reply AS lr ON lg.col= lr.some_other_col WHERE links_reply.some_other_col IS NULL
Mihai,

Ho avuto una domanda simile, che tiene conto anche della concorrenza. Vedi dba.stackexchange.com/questions/251875 .
pbillen,

Risposte:


19

Citando il manuale:

Esistono due modi per eliminare le righe in una tabella utilizzando le informazioni contenute in altre tabelle nel database: utilizzare i sottoselezioni o specificare ulteriori tabelle nella USINGclausola . Quale tecnica è più appropriata dipende dalle circostanze specifiche.

Enorme enfasi sulla mia. L'uso di informazioni che non sono contenute in un'altra tabella è un po 'complicato, ma ci sono soluzioni facili. Dall'arsenale di tecniche standard a ...

... un NOT EXISTSanti-semi-join è probabilmente il più semplice ed efficiente per DELETE:

DELETE FROM link_group lg
WHERE  NOT EXISTS (
   SELECT FROM link_reply lr
   WHERE  lr.which_group = lg.link_group_id
   );

Supponendo (poiché le definizioni di tabella non sono fornite) link_group_idcome nome di colonna per la chiave primaria di link_group.

Funziona anche la tecnica commentata da Mihai (applicata correttamente):

DELETE FROM link_group lg
USING  link_group      lg1
LEFT   JOIN link_reply lr ON lr.which_group = lg1.link_group_id
WHERE  lg1.link_group_id = lg.link_group_id
AND    lr.which_group IS NULL;

Ma poiché l'espressione di tabella nella USINGclausola è unita alla tabella di destinazione ( lgnell'esempio) con a CROSS JOIN, è necessaria un'altra istanza della stessa tabella di stepping stone ( lg1nell'esempio) per LEFT JOIN, che è meno elegante e in genere più lenta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.