如何在SQL Server中使用INNER JOIN从多个表中删除

Byr*_*ock 107 sql t-sql sql-server

在MySQL中,您可以使用语法

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
Run Code Online (Sandbox Code Playgroud)

我如何在SQL Server中执行相同的操作?

Joh*_*ibb 112

您可以在此示例中利用"已删除"伪表.就像是:

begin transaction;

   declare @deletedIds table ( id int );

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

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

   delete from t3
   from table3 as t3 ...

commit transaction;
Run Code Online (Sandbox Code Playgroud)

显然你可以做'输出删除'.在第二次删除时,如果您需要为第三个表加入某些内容.

作为旁注,您还可以在insert语句中插入.*,并在update语句中插入.*和deleted.*.

编辑: 此外,你有没有考虑在table1上添加一个触发器从table2 + 3删除?您将进入隐式事务,并且还将具有"inserted."和"deleted. "伪表.

  • 是否更好的只是DELETE FROM table1 WHERE id = x然后从下一个表删除而不是使用内部连接并通过所有这些额外的文本?基本上,跳过内连接我只需要2个简单的查询....或者这种方法更有效率? (2认同)

Aar*_*els 15

  1. 您始终可以在表的关系上设置级联删除.

  2. 您可以将多个删除封装在一个存储过程中.

  3. 您可以使用交易来确保一个单位的工作.

  • 绝对可以在join语句中删除,我只想一次从多个表中删除. (3认同)

top*_*hef 14

您可以在SQL Server中的DELETE中使用FROM子句中的JOIN语法,但您仍然只从第一个表中删除它,它是专有的Transact-SQL扩展,它是子查询的替代.

这里的例子:

 -- 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;
Run Code Online (Sandbox Code Playgroud)

  • 示例D: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; (3认同)

Pav*_*dek 11

从主表中删除一些记录以及从两个详细信息表中删除相应记录的示例:

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
Run Code Online (Sandbox Code Playgroud)

  • 你能用`SELECT INTO #DeleteIds`代替`CREATE TABLE 'DeleteIds`后跟`INSERT INTO 'DeleteIds...`吗? (2认同)

Mic*_*uen 9

只是想知道......在MySQL中真的有可能吗?它会删除t1和t2吗?或者我只是误解了这个问题.

但是,如果您只想删除具有多个连接条件的table1,则不要为要删除的表添加别名

这个:

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
Run Code Online (Sandbox Code Playgroud)

应该像这样写在MSSQL中工作:

DELETE table1
FROM table1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
Run Code Online (Sandbox Code Playgroud)

比较另外两个常见的RDBMS如何执行删除操作:

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


Yis*_*hai 7

基本上,您不必在事务中创建三个删除语句,首先是子项,然后是父项.如果这不是一次性的事情并且它的存在不会与任何现有的触发器设置冲突,那么设置级联删除是个好主意.