2012-04-13 18 views
16

Ho questi tavoli:Come eliminare i dati da più tabelle?

 
event  (evt_id, evt_code, reg_id) 

magnitude (mag_id, evt_id, value) 

trace  (trace_id, pt_id) 

point  (pt_id, evt_id) 

voglio eliminare tutte le righe di tutte le tabelle relative alla evt_id=1139.
Come faccio?

risposta

17

Se si ha il controllo sullo schema, farei utilizzare lo schema cascading deletes.

Dall'articolo (la parte più pertinente tradotto per il tuo esempio)

CREATE TABLE point 
(
    pt_id integer PRIMARY KEY, 
    evt_id integer REFERENCES event ON DELETE CASCADE 
) 

Se si dispone di cascate impostati, allora si può solo eliminare dal tavolo evento principale e tutti gli altri tavoli verrà ripulito automaticamente

Altrimenti, è necessario eliminare prima tutti i riferimenti, quindi eliminare la tabella principale. Si dovrebbe fare questo in una transazione per mantenere i dati coerenti

BEGIN; 
DELETE FROM trace WHERE EXISTS 
    (SELECT 1 FROM point WHERE evt_id = 1139 AND trace.pt_id = point.pt_id); 
DELETE FROM point where evt_id = 1139; 
DELETE FROM magnitude where evt_id = 1139; 
DELETE FROM event where evt_id = 1139; 
COMMIT; 
-3
$delete = 1139; 
$query = "DELETE FROM event, magnitude, point WHERE evt_id = '$delete'"; 
mysql_query($query, $con); 
$query = "DELETE FROM trace WHERE pt_id = '$delete'"; 

o semplicemente incollare questa affermazione in un file sql ed eseguirlo, o nella vostra finestra di query software di SQL, o metterla in un .php file ed eseguito sul server.

+1

Per quanto ne so, non è possibile eliminare da più tabelle come quella (ma potrei sbagliarmi). Tuttavia, almeno 'trace' non ha una colonna evt_id –

+0

Il database si trova sul server. Come eseguo questo file di query? – user1202766

+0

Sì, questa traccia vera non ha una colonna evt_id ma ha pt_id che è dalla tabella dei punti che ha la colonna evt_id..che è confusa! – user1202766

-1

Suppongo che gli ID nelle diverse tabelle corrispondano e vengano utilizzati per il collegamento. Suppongo inoltre che si desidera eliminare tutti i punti di traccia allthough sono collegati solo indirettamente evt_id

È possibile eliminare i record di tutte le tabelle come segue:

DELETE event , magnitude, trace, point 
FROM event left join magnitude on event.evt_id = magnitude.evt_id 
    left join point on event.evt_id = point.evt_id 
     left join trace on point.pt_id = trace.trace_id 
where event_id=1139 
+5

Questo funzionerà solo in mysql, e l'OP ha re-taggato questa domanda da mysql e postgresql a solo postgresql –

7

L'unico elemento non banale nella sua domanda sono elimina dalla tabella trace. Immagino sia sicuro assumere trace.pt_id riferendosi a point.pt_id?

O si definisce un foreign key with ON DELETE CASCADE e solo dimenticare la tavola trace (come già pointed out by @kevin) o si deve prendere cura di seconda mano righe.

Dal PostgreSQL 9,1 è possibile utilizzare data-modifying CTEs:

BEGIN; 

WITH x AS (
    DELETE FROM point WHERE evt_id = 1139 
    RETURNING pt_id 
    ) 
DELETE FROM trace 
USING x 
WHERE trace.pt_id = x.pt_id; 

DELETE FROM magnitude WHERE evt_id = 1139; 

DELETE FROM event WHERE evt_id = 1139; 

COMMIT; 

La RETURNING clause dei rendimenti DELETE FROM point tutti i colpiti pt_id - quelli sono a loro volta utilizzati per eliminare tutte le righe corrispondenti da trace.

Non hai menzionato se la concorrenza è un problema nel tuo caso. Se lo è, e se si desidera evitare possibili risultati nella finestra di tempo breve tra le eliminazioni in cui le righe per evt_id = 1139 sono presenti in una tabella mentre già eliminate da un'altra, eseguire il tutto in una transazione .
Se non ti interessa, ignora BEGIN e COMMIT.

Problemi correlati