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

时间:2009-04-23 22:06:57

标签: sql sql-server tsql

在MySQL中,您可以使用语法

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

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

13 个答案:

答案 0 :(得分:110)

您可以利用此示例中的“已删除”伪表。类似的东西:

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;

显然你可以做'删除输出'。在第二次删除时,如果你需要为第三个表加入一些东西。

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

修改 另外,您是否考虑在table1上添加触发器以从table2 + 3中删除?您将进入隐式事务,并且还可以使用“inserted。”和“deleted。”伪表。

答案 1 :(得分:15)

  1. 您始终可以对表格的关系设置级联删除。

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

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

答案 2 :(得分:14)

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

来自示例here

 -- 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;

答案 3 :(得分: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

答案 4 :(得分:9)

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

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

这样:

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

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

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

以对比其他两个常见的RDBMS如何执行删除操作:

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

答案 5 :(得分:7)

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

答案 6 :(得分:3)

在SQL Server中,无法使用join删除多个表。 所以你必须先删除孩子,然后再删除父母。

答案 7 :(得分:2)

所有人都被指出了。只需在父DELETE ON CASCADE上使用table,或从child-table删除parent

答案 8 :(得分:2)

这是一种在不离开孤儿的情况下删除记录的替代方法。


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

答案 9 :(得分:1)

正如Aaron已经指出的那样,您可以将删除行为设置为CASCADE,并在删除父记录时删除子记录。除非你想要某种其他魔法发生(在这种情况下,Aaron的回复中的第2,3点会很有用),我不明白为什么你需要删除内连接。

答案 10 :(得分:0)

以John Gibb的答案为基础,删除两个具有FK关系的表中的一组数据:

multi-dimensioned list

答案 11 :(得分:-3)

DELETE     TABLE1 LIN
FROM TABLE1 LIN
INNER JOIN TABLE2 LCS ON  CONDITION
WHERE CONDITION

答案 12 :(得分:-4)

$ sql ="从basic_tbleducation_tbl删除, personal_tbladdress_tbldepartment_tbl 使用 basic_tbleducation_tblpersonal_tbladdress_tbldepartment_tbl 哪里 b_id = e_id = p_id = a_id = d_id ='" $ ID"' &#34 ;;  $ RS = mysqli_query($ CON,$ SQL);