【发布时间】:2025-12-05 15:50:02
【问题描述】:
在 MySQL 中你可以使用语法
DELETE t1,t2
FROM table1 AS t1
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
我如何在 SQL Server 中做同样的事情?
【问题讨论】:
标签: sql sql-server tsql
在 MySQL 中你可以使用语法
DELETE t1,t2
FROM table1 AS t1
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...
我如何在 SQL Server 中做同样的事情?
【问题讨论】:
标签: sql sql-server tsql
您可以利用此示例中的“已删除”伪表。比如:
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;
显然,您可以执行“输出已删除”。在第二次删除时,如果您需要为第三张表加入一些东西。
附带说明一下,您还可以在插入语句中执行插入。*,在更新语句中同时插入。* 和删除。*。
编辑: 另外,您是否考虑过在 table1 上添加触发器以从 table2 + 3 中删除?您将处于一个隐式事务中,并且还可以使用“inserted.”和“deleted.”伪表。
【讨论】:
您始终可以对表的关系设置级联删除。
您可以将多个删除操作封装在一个存储过程中。
您可以使用事务来确保一个工作单元。
【讨论】:
您可以在 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;
【讨论】:
删除主表部分记录和两个明细表对应记录的示例:
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
【讨论】:
SELECT INTO #DeleteIds代替CREATE TABLE 'DeleteIds,然后是INSERT INTO 'DeleteIds...吗?
基本上,您必须在事务中创建三个删除语句,首先是子项,然后是父项。如果这不是一次性的事情并且它的存在不会与任何现有的触发器设置冲突,那么设置级联删除是一个好主意。
【讨论】:
只是想知道......这在 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
【讨论】:
在 SQL Server 中,无法使用连接从多个表中删除记录。 所以你必须先从子级删除,然后再删除父级。
【讨论】:
这是在不留下孤儿的情况下删除记录的另一种方法。
声明 @user Table(keyValue int , someString varchar(10)) 插入@user 值(1,'1 值') 插入@user 值(2,'2 值') 插入@user 值(3,'3 值') 声明@password 表(keyValue int,详细信息 varchar(10)) 插入@password 值(1,'1 密码') 插入@password 值(2,'2密码') 插入@password 值(3,'3 密码') --删除前 select * from @password a 内连接 @user b a.keyvalue = b.keyvalue select * into #deletedID from @user where keyvalue=1 - 这与输出示例类似 删除键值 =1 的 @user 删除键值所在的@password(从#deletedid 中选择键值) --删除后-- select * from @password a 内连接 @user b a.keyvalue = b.keyvalue【讨论】:
一切都已被指出。只需在父级table 上使用DELETE ON CASCADE 或从child-table 中删除,然后再使用parent。
【讨论】:
正如 Aaron 已经指出的那样,您可以将删除行为设置为 CASCADE,这将在删除父记录时删除子记录。除非您希望发生某种其他魔法(在这种情况下,Aaron 的回复的第 2、3 点会很有用),否则我不明白您为什么需要使用内部连接进行删除。
【讨论】:
以 John Gibb 的回答为基础,删除具有 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;
【讨论】:
DELETE TABLE1 LIN
FROM TABLE1 LIN
INNER JOIN TABLE2 LCS ON CONDITION
WHERE CONDITION
【讨论】:
$sql="删除basic_tbl,education_tbl,
personal_tbl,address_tbl,department_tbl
使用
basic_tbl,education_tbl,
personal_tbl,address_tbl,department_tbl
在哪里
b_id=e_id=p_id=a_id=d_id='".$id."'
";
$rs=mysqli_query($con,$sql);
【讨论】: