2009-11-23 26 views
24

Questo è probabilmente molto semplice, ma è lunedì mattina. Ho due tabelle:SQL Elimina righe in base a un'altra tabella

Tabella 1:

Field  | Type    | Null | Key | Default | Extra 
id   | int(32) unsigned | NO | PRI | NULL | auto_increment 
group  | int(32)   | NO |  | 0  |     

Table2:

Field  | Type    | Null | Key | Default | Extra 
group  | int(32)   | NO |  | 0  | 

Ignorare altri campi ... Vorrei una singola SQL DELETE che eliminare tutte le righe in Tabella 1 per il quale esiste un Table2.group uguale a Table1.group. Pertanto, se una riga di Table1 ha group = 69, quella riga deve essere cancellata se e solo se esiste una riga in Table2 con group = 69.

Grazie per qualsiasi aiuto.

risposta

35

Credo che questo sia ciò che si vuole:

DELETE FROM `table1` 
WHERE `group` in (SELECT DISTINCT `group` FROM `table2`) 
+0

muchos gracias. –

+0

Salvato la mia giornata! Grazie @ Jay! – Lefteris

+0

È semplice e molto efficace. Funziona nel server SQL (ma senza le virgolette singole). –

7

Qualcosa di simile

delete from table1 where group in (select group from table2) 
+0

I' d selezionare distinto nella subquery –

+0

Non sta utilizzando distinto solo più lavoro per rimuovere i duplicati dalla sottoquery? Lo lascerei fuori. –

1

Fuori della parte superiore della mia testa:

delete from Table1 where id in (select id from table1 inner join table2 on Table1.group = Table2.group) 

ho fatto un po 'diverso rispetto altri poster - Penso che se c'è un numero elevato di righe su Table2 questo potrebbe essere migliore. Qualcuno può dirmi per favore?

+0

Torna ancora a un elenco IN, che è problematico. Considera l'esempio @AmoBrinkman o il BT26; questi non richiedono il motore per creare un array di grandi dimensioni. Ad es., potresti cambiare "where id in" a "where exists" e probabilmente dovrebbe funzionare in modo identico, ma molto più veloce e "affatto" per grandi volumi. – troy

8

La bella soluzione è solo scrivendo la SQL come dite voi stessi già:

DELETE FROM Table1 
WHERE 
    EXISTS(SELECT 1 FROM Table2 WHERE Table2.Group = Table1.Group) 

saluti, Arno Brinkman

+1

Mi piace questa soluzione che contiene una clausola WHERE.Ciò significa che funzionerà ancora se si desidera eliminare solo le righe corrispondenti a più colonne nelle due tabelle. – malamut

+0

@ArnoBrinkman aggiungerebbe 'LIMIT 1' a:' EXISTS (SELECT 1 FROM Table2 WHERE Table2.Group = Table1.Group LIMIT 1) 'help? –

16

Credo che in questo modo è più veloce:

DELETE FROM t1 USING table1 t1 INNER JOIN table2 t2 ON (t1.group = t2.group); 
+0

In SQL Server ciò sembra non funzionare: SSMS mi invia questo messaggio per la query precedente: ** Sintassi non corretta vicino a "USING". ** – Oliver

+4

Nel caso di SQL Server la sintassi è: ELIMINA DA T1 ** FROM t1 ** INNER JOIN T2 ON t1.ID = t2.ID Elimina tutte le righe da t1 presenti sulla tabella t2 in base all'ID ma è possibile aggiungere più condizioni alla clausola inner join come normalmente con l'operatore AND. Notare il secondo Da ?! Non è lì per errore e questo è ciò che rende l'utilizzo di lavoro su SQL Server. – kuklei

+0

Se stai cancellando da tabelle InnoDB molto grandi, potresti prendere in considerazione l'aumento di 'innodb_buffer_pool_size'. Questo primo errore è fallito dopo 30 minuti di esecuzione, quindi sono aumentato a 512 MB e sono riuscito a rimuovere circa 13 milioni di record extra. Le tabelle a cui stavo partecipando erano 44 milioni e 23 milioni di record, rispettivamente al loro ordine nella query. –

Problemi correlati