tsql - T-SQL:通过join选择要删除的行

  显示原文与译文双语对照的内容

场景:

假设我有两个表,TableA和 TableB 。 tableb键的主键是单列( 叫牌),是TableA中的外键列。

在我的情况下,我要删除TableA中与TableB中特定行链接的所有行: 我可以通过加入? 删除从联接中提取的所有行?


DELETE FROM TableA 
FROM
 TableA a
 INNER JOIN TableB b
 ON b.BId = a.BId
 AND [my filter condition]

还是我不得不这样做:


DELETE FROM TableA
WHERE
 BId IN (SELECT BId FROM TableB WHERE [my filter condition])

我问的原因是,在处理较大的表格时,第一个选项应该是 effecient 。

谢谢!

时间:

MySQL几乎是相同的,但是你必须使用表别名"删除"这个词后:


DELETE a
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]

试图使用access数据库进行这项操作,发现我需要在删除后使用 。*


DELETE a.*
FROM TableA AS a
INNER JOIN TableB AS b
ON a.BId = b.BId
WHERE [filter condition]

上语法在 Interbase 2007中不起作用。 相反,我不得不使用类似:


DELETE FROM TableA a WHERE [filter condition on TableA] 
 AND (a.BId IN (SELECT a.BId FROM TableB b JOIN TableA a 
 ON a.BId = b.BId 
 WHERE [filter condition on TableB]))

( 注意,Interbase不支持作为别名的关键字)

假设你有 2个表,其中一个带有主集( 例如。 雇员) 和带有子集合的员工( 例如。 依赖项),你希望删除从属表中的所有数据,这些数据行不能用主表中的任何行进行键处理。


delete from Dependents where EmpID in (
select d.EmpID from Employees e 
 right join Dependents d on e.EmpID = d.EmpID
 where e.EmpID is null)

这里要注意的是你只是收集的'数组'EmpIDs首先从加入,使用的一组EmpIDs家属表删除操作。

在SQLite中,惟一的工作是类似于beauXjames的答案。

似乎是这样 DELETE FROM table1 WHERE table1.col1 IN (SOME TEMPORARY TABLE); ,一些临时表可以用板条箱包装的选择和连接两个表,你可以过滤这个临时表基于条件是你要删除的记录在表1.

我正在使用这个


DELETE TableA 
FROM TableA a
INNER JOIN
TableB b on b.Bid = a.Bid
AND [condition]

@TheTXI 方法足够好,但我阅读了答案和注释,我发现必须回答的一个问题是使用条件或者作为加入条件。 所以我决定测试它并编写一个 Fragment,但在它们之间没有发现有意义的差异。 你可以在这里看到sql脚本,重要的是我更喜欢将它写成 commnet,因为这不是正确的答案,但它很大,无法放入评论,请原谅。


Declare @TableA Table
(
 aId INT,
 aName VARCHAR(50),
 bId INT
)
Declare @TableB Table
(
 bId INT,
 bName VARCHAR(50) 
)

Declare @TableC Table
(
 cId INT,
 cName VARCHAR(50),
 dId INT
)
Declare @TableD Table
(
 dId INT,
 dName VARCHAR(50) 
)

DECLARE @StartTime DATETIME;
SELECT @startTime = GETDATE();

DECLARE @i INT;

SET @i = 1;

WHILE @i <1000000
BEGIN
 INSERT INTO @TableB VALUES(@i, 'nameB:' + CONVERT(VARCHAR, @i))
 INSERT INTO @TableA VALUES(@i+5, 'nameA:' + CONVERT(VARCHAR, @i+5), @i)

 SET @i = @i + 1;
END

SELECT @startTime = GETDATE()

DELETE a
--SELECT *
FROM @TableA a
Inner Join @TableB b
ON a.BId = b.BId
WHERE a.aName LIKE '%5'

SELECT Duration = DATEDIFF(ms,@StartTime,GETDATE())

SET @i = 1;
WHILE @i <1000000
BEGIN
 INSERT INTO @TableD VALUES(@i, 'nameB:' + CONVERT(VARCHAR, @i))
 INSERT INTO @TableC VALUES(@i+5, 'nameA:' + CONVERT(VARCHAR, @i+5), @i)

 SET @i = @i + 1;
END

SELECT @startTime = GETDATE()

DELETE c
--SELECT *
FROM @TableC c
Inner Join @TableD d
ON c.DId = d.DId
AND c.cName LIKE '%5'

SELECT Duration = DATEDIFF(ms,@StartTime,GETDATE())

如果你能从这个脚本中获得很好的理由,或者编写另一个有用的工具,请共享。 感谢并希望这里帮助。

...