Adr*_*ore 36 t-sql sql-server sql-server-2008
我有两个表(任务和时间条目),它们通过外键连接(TimeEntries.TaskID引用Tasks.ID)
现在,我想删除任务中未被TimeEntries表引用的所有行.我认为这应该有效:
DELETE FROM Tasks WHERE ID not IN (SELECT TaskID FROM TimeEntries)
Run Code Online (Sandbox Code Playgroud)
但它会影响0行,即使Tasks表中有很多未引用的行.
这可能是什么问题?当然我可以写一个迭代所有行的SP,但看起来这可以在一个衬里完成.
我想这是睡眠时间下溢错误之一.请帮忙!
And*_*mar 52
有一个臭名昭着的陷阱not in.基本上,id not in (1,2,3)是简写:
id <> 1 and id <> 2 and id <> 3
Run Code Online (Sandbox Code Playgroud)
现在,如果您的TimeEntries表包含任何带有a TaskID的行null,则not in转换为:
ID <> null and ID <> 1 and ID <> 2 AND ...
Run Code Online (Sandbox Code Playgroud)
与之比较的结果null总是如此unknown.由于unknown在SQL中不是这样,该where子句会过滤掉所有行,并且最终不会删除任何行.
一个简单的修复是子查询中的附加where子句:
DELETE FROM Tasks
WHERE ID not IN
(
SELECT TaskID
FROM TimeEntries
WHERE TaskID is not null
)
Run Code Online (Sandbox Code Playgroud)
SQL*_*ace 22
一种方法,这将处理您使用空值的"问题"(请参阅下面的链接了解更多信息)
DELETE FROM Tasks
WHERE NOT EXISTS (SELECT 1 FROM TimeEntries
WHERE TimeEntries.TaskID = Tasks.ID )
Run Code Online (Sandbox Code Playgroud)
要了解您遇到的问题,请查看从一个表中选择另一个表中不存在的所有行
由于您运行的是SQL 2008,因此可以使用漂亮的新合并语法.
MERGE Tasks AS target
USING TimeEntries as Source ON (Target.TaskID=Source.TaskID)
WHEN NOT MATCHED BY Source THEN DELETE;
Run Code Online (Sandbox Code Playgroud)
我知道这是旧的,但我想知道为什么没有人提到这里描述的删除查询。所以,供参考:
DELETE FROM Tasks
FROM Tasks LEFT OUTER JOIN
TimeEntries ON TimeEntries.TaskID = Tasks.ID
WHERE TimeEntries.TaskID IS NULL;
Run Code Online (Sandbox Code Playgroud)
此语法与 ISO 不兼容,因此仅适用于 T-SQL。