Eliminar todas las filas de una tabla basada en otra tabla


81

¡Parece que no puedo recordar esta consulta!

Quiero eliminar todas las filas en la tabla1 cuyas ID son las mismas que en la Tabla2.

Entonces:

DELETE table1 t1
 WHERE t1.ID = t2.ID

Sé que puedo hacer un ID DÓNDE EN (SELECCIONAR ID DE LA tabla2) pero quiero hacer esta consulta usando un JOIN si es posible.


¿Por qué quieres unirte?
tster

¿Qué planeas hacer con esta pregunta: stackoverflow.com/questions/1590709/…
OMG Ponies

Porque las uniones suelen ser más rápidas.
HLGEM

@tster Quizás sea una tabla temporal de identificadores que deben eliminarse
Stephen Mesa

1
@HLGEM ¿Está diciendo que el optimizador de consultas no es lo suficientemente inteligente como para hacer una simple "eliminación de X donde XY IN (seleccione Foo de la barra)" tan rápido como hacer una combinación? Confiaría en el optimizador sobre el instinto.
tster

Respuestas:



88
DELETE t1 
FROM Table1 t1
JOIN Table2 t2 ON t1.ID = t2.ID;

Siempre uso el alias en la declaración de eliminación, ya que evita el accidente.

DELETE Table1 

causado al no resaltar toda la consulta antes de ejecutarla.


5
Votar a favor principalmente por el comentario de "usar siempre el alias" Gran idea.
rosscova

35

No hay una solución en ANSI SQL para usar combinaciones en eliminaciones, AFAIK.

DELETE FROM Table1
WHERE Table1.id IN (SELECT Table2.id FROM Table2)

Posteriormente editar

Otra solución (a veces funciona más rápido):

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

Su pregunta dice al final que quiere usar una combinación en lugar de la cláusula IN.
Stephen Mesa

21

La implementación de PostgreSQL sería:

DELETE FROM t1
USING t2
WHERE t1.id = t2.id;

4

Prueba esto:

DELETE Table1
FROM Table1 t1, Table2 t2
WHERE t1.ID = t2.ID;

o

DELETE Table1
FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID;

3

Creo que podrías obtener un poco más de rendimiento si intentas esto

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

3

Esto eliminará todas las filas Table1que coincidan con los criterios:

DELETE Table1 
FROM Table2 
WHERE Table1.JoinColumn = Table2.JoinColumn And Table1.SomeStuff = 'SomeStuff'

2

Encontré este enlace útil

Copiado de allí

A menudo, uno desea eliminar algunos registros de una tabla según los criterios de otra tabla. ¿Cómo se elimina de una de esas tablas sin eliminar los registros en ambas tablas?

DELETE DeletingFromTable
     FROM DeletingFromTable INNER JOIN CriteriaTable
     ON DeletingFromTable.field_id = CriteriaTable.id
     WHERE CriteriaTable.criteria = "value";

La clave es que especifique el nombre de la tabla que se eliminará como SELECT. Entonces, JOIN y WHERE hacen la selección y la limitación, mientras que DELETE hace la eliminación. Sin embargo, no está limitado a una sola mesa. Si tiene una relación de varios a varios (por ejemplo, revistas y suscriptores, unidos por una suscripción) y está eliminando un suscriptor, también debe eliminar todos los registros potenciales del modelo de unión.

 DELETE subscribers, subscriptions
     FROM subscribers INNER JOIN subscriptions 
       ON subscribers.id = subscriptions.subscriber_id
     INNER JOIN magazines 
       ON subscriptions.magazine_id = magazines.id
     WHERE subscribers.name='Wes';

La eliminación de registros con una combinación también se puede hacer con LEFT JOIN y WHERE para ver si la tabla unida era NULL, de modo que pueda eliminar registros en una tabla que no tiene una coincidencia (como en preparación para agregar una relación. ) Ejemplo de publicación por venir.


2

Dado que el OP no solicita una base de datos específica, es mejor utilizar una declaración compatible con el estándar. Solo MERGEestá en el estándar SQL para eliminar (o actualizar) filas mientras se une algo en la tabla de destino.

merge table1 t1
    using (
        select t2.ID
            from table2 t2
    ) as d
    on t1.ID = d.ID
    when matched then delete;

MERGEtiene una semántica más estricta, protegiendo de algunos casos de error que pueden pasar desapercibidos con DELETE ... FROM. Hace cumplir la 'unicidad' de la coincidencia: si muchas filas en la fuente (la declaración dentro using) coinciden con la misma fila en el destino, la fusión debe cancelarse y el motor SQL debe generar un error.


esto es más limpio que la construcción delete-join
asakura89


0

Para eliminar registros de tabla basados ​​en otra tabla

     Delete From Table1 a,Table2 b where a.id=b.id

    Or

      DELETE FROM Table1
    WHERE Table1.id IN (SELECT Table2.id FROM Table2)

  Or

        DELETE Table1
     FROM Table1 t1 INNER JOIN Table2 t2 ON t1.ID = t2.ID;

0

Esto es viejo, lo sé, pero solo un indicador para cualquiera que use este culo como referencia. Acabo de probar esto y si está utilizando Oracle, JOIN no funciona en las declaraciones DELETE. Recibes el siguiente mensaje:

ORA-00933: El comando SQL no finalizó correctamente.


Consulte esta respuesta a otra pregunta para ver un ejemplo de cómo escribir una eliminación con combinación en Oracle.
Frédéric

0

Si bien el OP no quiere usar una declaración 'in', en respuesta a Ankur Gupta, esta fue la forma más fácil que encontré para eliminar los registros en una tabla que no existían en otra tabla, en una relación de uno a muchos :

DELETE
FROM Table1 as t1
WHERE ID_Number NOT IN
(SELECT ID_Number FROM Table2 as t2)

Funcionó de maravilla en Access 2016, para mí.


0

A menudo hago cosas como el siguiente ejemplo inventado. (Este ejemplo es de Informix SE que se ejecuta en Linux).

El objetivo de este ejemplo es eliminar todos los registros de transacciones de exención / reducción de bienes raíces, porque la aplicación de reducción tiene un error, según la información de la tabla real_estate.

En este caso, last_update != nullsignifica que la cuenta no está cerrada, y res_exempt != 'p'significa que las cuentas no son propiedad personal (equipo / mobiliario comercial).

delete from trans 
where   yr = '16'
and     tran_date = '01/22/2016'
and     acct_type = 'r'
and     tran_type = 'a'
and     bill_no in
(select acct_no from real_estate where last_update is not null
 and res_exempt != 'p');

Me gusta este método porque los criterios de filtrado, al menos para mí, son más fáciles de leer al crear la consulta y de entender dentro de muchos meses cuando los miro y me pregunto qué estaba pensando.


0
delete
    table1
from 
    t2
where
    table1.ID=t2.ID

Funciona en mssql

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.