Cómo puedo eliminar de varias tablas usando INNER JOIN en SQL server


En MySQL se puede utilizar la sintaxis

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

¿Cómo hago lo mismo en SQL Server?

Author: OMG Ponies, 2009-04-24

13 answers

Puede aprovechar la pseudo tabla "deleted" en este ejemplo. Algo como:

begin transaction;

   declare @deletedIds table ( id int );

   delete t1
   output deleted.id into @deletedIds
   from table1 t1
    join table2 t2
      on t2.id = t1.id
    join table3 t3
      on t3.id = t2.id;

   delete t2
   from table2 t2
    join @deletedIds d
      on d.id = t2.id;

   delete t3
   from table3 t3 ...

commit transaction;

Obviamente puedes hacer un 'output deleted.'en la segunda borra también, si necesitabas algo para unirte a la tercera mesa.

Como nota al margen, también puede hacer insertado.* en una instrucción insert, y ambas insertadas.* y suprimido.* en una declaración de actualización.

EDITAR: Además, ¿ha considerado agregar un disparador en la tabla1 para eliminar de la tabla2 + 3? Estarás dentro. de una transacción implícita, y también tendrá el " insertado. "y" suprimido. " pseudo-tablas disponibles.

 97
Author: John Gibb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-21 22:51:09
  1. Siempre puede configurar eliminaciones en cascada en las relaciones de las tablas.

  2. Puede encapsular las eliminaciones múltiples en un procedimiento almacenado.

  3. Puede utilizar una transacción para garantizar una unidad de trabajo.

 14
Author: Aaron Daniels,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-05 21:26:14

Puede usar la sintaxis de unión en la cláusula FROM en DELETE en SQL Server, pero todavía elimina de la primera tabla solo y es la extensión propietaria de Transact-SQL que es alternativa a la sub-consulta.

Del ejemplo aquí:

 -- Transact-SQL extension
 DELETE 
   FROM Sales.SalesPersonQuotaHistory 
     FROM Sales.SalesPersonQuotaHistory AS spqh INNER JOIN 
          Sales.SalesPerson AS sp ON spqh.BusinessEntityID = sp.BusinessEntityID
    WHERE sp.SalesYTD > 2500000.00;
 14
Author: topchef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-09 18:01:58

Ejemplo para eliminar algunos registros de la tabla maestra y los registros correspondientes de dos tablas de detalles:

BEGIN TRAN

  -- create temporary table for deleted IDs
  CREATE TABLE #DeleteIds (
    Id INT NOT NULL PRIMARY KEY
  )

  -- save IDs of master table records (you want to delete) to temporary table    
  INSERT INTO #DeleteIds(Id)
  SELECT DISTINCT mt.MasterTableId
  FROM MasterTable mt 
  INNER JOIN ... 
  WHERE ...  

  -- delete from first detail table using join syntax
  DELETE d
  FROM DetailTable_1 D
  INNER JOIN #DeleteIds X
    ON D.MasterTableId = X.Id


  -- delete from second detail table using IN clause  
  DELETE FROM DetailTable_2
  WHERE MasterTableId IN (
    SELECT X.Id
    FROM #DeleteIds X
  )


  -- and finally delete from master table
  DELETE d
  FROM MasterTable D
  INNER JOIN #DeleteIds X
    ON D.MasterTableId = X.Id

  -- do not forget to drop the temp table
  DROP TABLE #DeleteIds

COMMIT
 11
Author: Pavel Hodek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-07 13:03:59

Solo me preguntaba.. ¿es eso realmente posible en MySQL? ¿eliminará t1 y t2? o simplemente malinterpreté la pregunta.

Pero si solo desea eliminar tabla1 con múltiples condiciones de unión, simplemente no ponga un alias a la tabla que desea eliminar

Esto:

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

Debe escribirse así para trabajar en MSSQL:

DELETE table1
FROM table1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

Para contrastar cómo los otros dos RDBMS comunes hacen un delete operación:

Http://mssql-to-postgresql.blogspot.com/2007/12/deleting-duplicates-in-postgresql-ms.html

 9
Author: Michael Buen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-24 07:03:55

Básicamente, no, tiene que hacer tres declaraciones de borrado en una transacción, primero los hijos y luego los padres. Configurar eliminaciones en cascada es una buena idea si esto no es algo único y su existencia no entrará en conflicto con ninguna configuración de disparador existente.

 7
Author: Yishai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-23 22:40:32

En SQL server no hay forma de eliminar varias tablas usando join. Por lo tanto, primero debe eliminar del niño antes de eliminar el padre del formulario.

 2
Author: tiny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-24 06:50:01

Esta es una forma alternativa de eliminar registros sin dejar huérfanos.


Declare @user Table(keyValue int  , someString varchar(10))
insert into @user
values(1,'1 value')

insert into @user
values(2,'2 value')

insert into @user
values(3,'3 value')

Declare @password Table(  keyValue int , details varchar(10))
insert into @password
values(1,'1 Password')
insert into @password
values(2,'2 Password')
insert into @password
values(3,'3 Password')

        --before deletion
  select * from @password a inner join @user b
                on a.keyvalue = b.keyvalue
  select * into #deletedID from @user where keyvalue=1 -- this works like the output example
  delete  @user where keyvalue =1
  delete @password where keyvalue in (select keyvalue from #deletedid)

  --After deletion--
  select * from @password a inner join @user b
                on a.keyvalue = b.keyvalue

 2
Author: hidden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-14 16:15:38

Todo ha sido señalado. Simplemente use DELETE ON CASCADE en el padre table o elimine de child-table a parent.

 2
Author: kayode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-24 12:39:34

Como Aaron ya ha señalado, puede establecer el comportamiento de eliminación en CASCADA y eso eliminará los registros hijos cuando se elimine un registro padre. A menos que quieras que ocurra algún otro tipo de magia (en cuyo caso los puntos 2, 3 de la respuesta de Aaron serían útiles), no veo por qué necesitas eliminar con uniones internas.

 1
Author: Peter Perháč,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-23 22:17:05

Para construir sobre la respuesta de John Gibb, para eliminar un conjunto de datos en dos tablas con una relación FK:

--*** To delete from tblMain which JOINs to (has a FK of) tblReferredTo's PK  
--       i.e.  ON tblMain.Refer_FK = tblReferredTo.ID
--*** !!! If you're CERTAIN that no other rows anywhere also refer to the 
--      specific rows in tblReferredTo !!!
BEGIN TRAN;

    --*** Keep the ID's from tblReferredTo when we DELETE from tblMain
    DECLARE @tblDeletedRefs TABLE ( ID INT );
    --*** DELETE from the referring table first
    DELETE FROM tblMain 
    OUTPUT DELETED.Refer_FK INTO @tblDeletedRefs  -- doesn't matter that this isn't DISTINCT, the following DELETE still works.
    WHERE ..... -- be careful if filtering, what if other rows 
                --   in tblMain (or elsewhere) also point to the tblReferredTo rows?

    --*** Now we can remove the referred to rows, even though tblMain no longer refers to them.
    DELETE tblReferredTo
    FROM   tblReferredTo INNER JOIN @tblDeletedRefs Removed  
            ON tblReferredTo.ID = Removed.ID;

COMMIT TRAN;
 0
Author: AjV Jsy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-24 10:27:00
DELETE     TABLE1 LIN
FROM TABLE1 LIN
INNER JOIN TABLE2 LCS ON  CONDITION
WHERE CONDITION
 -3
Author: ARUN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-13 13:14:11

Sql sql= " DELETE FROM basic_tbl, education_tbl, personal_tbl ,address_tbl,department_tbl UTILIZAR basic_tbl,education_tbl, personal_tbl ,address_tbl,department_tbl DONDE b_id=e_id=p_id=a_id=d_id='".$id."' "; rs rs=mysqli_query (sql con, sql sql);

 -4
Author: Dharmesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-17 18:32:20