How do I delete from multiple tables using INNER JOIN in SQL server
在MySQL中,您可以使用语法
1 2 3 4 | DELETE t1,t2 FROM table1 AS t1 INNER JOIN table2 t2 ... INNER JOIN table3 t3 ... |
如何在SQL Server中执行相同的操作?
您可以利用本例中的"已删除"伪表。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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; |
。
显然,如果您需要为第三个表加入一些内容,也可以在第二次删除时执行"output deleted."。
作为补充说明,您还可以在insert语句中执行inserted.*操作,在update语句中执行inserted.*和deleted.*操作。
编辑:此外,是否考虑在表1上添加触发器以从表2+3中删除?您将进入一个隐式事务,并且还可以使用"inserted."和"deleted."伪表。
您始终可以在表的关系上设置级联删除。
可以在一个存储过程中封装多个删除。
您可以使用事务来确保一个工作单元。
您可以在SQL Server中的DELETE中的FROM子句中使用联接语法,但仍然只从第一个表中删除,它是专用的Transact-SQL扩展,可以替代子查询。
从这里的例子来看:
1 2 3 4 5 6 | -- 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; |
例如,从主表中删除一些记录,并从两个明细表中删除相应的记录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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 |
只是想知道……这在MySQL中真的可行吗?它将删除T1和T2?或者我只是误解了这个问题。
但是,如果只想删除具有多个联接条件的表1,只需不要对要删除的表进行别名。
这是:
1 2 3 4 | DELETE t1,t2 FROM table1 AS t1 INNER JOIN table2 t2 ... INNER JOIN table3 t3 ... |
号
应该这样写才能在MSSQL中工作:
1 2 3 4 | 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
基本上,不,您必须在一个事务中生成三条删除语句,先是子语句,然后是父语句。如果这不是一次性的事情,并且它的存在不会与任何现有的触发器设置冲突,那么设置级联删除是一个好主意。
在SQL Server中,无法使用join删除多个表。因此,在删除窗体父级之前,必须先从子级删除。
这是删除记录而不留下孤儿的另一种方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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 |
。
所有的都被指出了。只需在父级
正如Aaron已经指出的,您可以将"删除行为"设置为"层叠",这样在删除父记录时将删除子记录。除非您希望发生某种其他魔力(在这种情况下,Aaron回复的第2点、第3点会很有用),否则我不明白为什么需要使用内部联接删除。
基于John Gibb的回答,删除两个表中具有FK关系的一组数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | --*** 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; |
1 2 3 4 | DELETE TABLE1 LIN FROM TABLE1 LIN INNER JOIN TABLE2 LCS ON CONDITION WHERE CONDITION |
。
$sql="从