在以下情况下,是否有一种无需使用关键字IN
即可从SQL Server删除记录的有效方法:
-- If Documents were deleted, remove them from your ocean
DELETE FROM IndexHistory
WHERE DocId IN (SELECT IH.Docid
FROM IndexHistory IH
LEFT JOIN IndexedLineItems I ON IH.Docid = I.DocId
WHERE I.Docid IS NULL)
如果您研究这种情况,则您要在圆括号内的所有查询中删除所有记录。
有记录的事实表明,使用“ IN”效率低下。因此,人们会认为应该有一种不用'IN'删除它们的方法,因为无需使用“ IN”就可以识别所有记录。
例如,我在想这样的事情是可能的,但是我没有正确的语法:
DELETE FROM IndexHistory IH
LEFT JOIN IndexedLineItems I ON IH.Docid = I.DocId
WHERE I.Docid IS NULL
我很欣赏答案可能仍然是“不,不可能。”
如果不可能,则可能是改善Microsoft语言的建议。在我这样做之前,我想我会在这里发贴,看看我是否缺少某些东西。
答案 0 :(得分:5)
出于可读性原因,我更喜欢CTE,也可以更改为使用SELECT
来查看要删除的内容。这个NOT EXISTS
可能也更有效:
WITH DeleteData AS
(
SELECT IH.Docid
FROM IndexHistory IH
WHERE NOT EXISTS( SELECT 1 FROM IndexedLineItems I
WHERE I.DocId = IH.DocId)
)
DELETE FROM DeleteData
您不需要从此CTE到表的其他联接,因为仅选择了一个表。
答案 1 :(得分:5)
使用not exists
:
Delete ih from IndexHistory ih
where not exists (select 1 from IndexedLineItems ili where ih.Docid = ili.DocId)
答案 2 :(得分:1)
换一种说法,改用内部联接,这样就只删除匹配项:
DELETE FROM IndexHistory IH
JOIN IndexedLineItems I ON IH.Docid = I.DocId
WHERE I.Docid IS NOT NULL
答案 3 :(得分:0)
这很好...
DELETE IH
FROM IndexHistory IH
Left JOIN IndexedLineItems LI
ON IH.Docid = LI.DocId
WHERE LI.DocId is Null