使用T-SQL删除记录而不使用IN子句

Hea*_*ans 3 t-sql sql-server syntax subquery

是否有一种有效的方法从SQL Server中删除记录而不使用IN以下方案中的关键字:

-- 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)
Run Code Online (Sandbox Code Playgroud)

如果您研究此场景,则您要从括号内的查询中删除所有记录.

据记载,使用"IN"是低效的.

因此,人们会认为应该有一种方法可以在没有"IN"的情况下删除它们,因为所有记录都可以在不使用"IN"的情况下识别.

因此,例如,我认为这样的事情可能是可能的,但我没有正确的语法:

DELETE FROM IndexHistory IH 
LEFT JOIN IndexedLineItems I ON IH.Docid = I.DocId
WHERE I.Docid IS NULL
Run Code Online (Sandbox Code Playgroud)

如果答案是"不,那是不可能的",请不要低估这一点.

这是一个很好的问题.

如果不可能,也许可以建议改进Microsoft的语言.

在我这样做之前,我想我会在这个板上张贴,看看我是否遗漏了一些东西....

Tim*_*ter 5

我更喜欢CTE的可读性原因,它也可以更改为使用a 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
Run Code Online (Sandbox Code Playgroud)

您不需要从此CTE到表的其他JOIN,因为只选择了一个表.


Gor*_*off 5

用途not exists:

Delete ih from IndexHistory ih
    where not exists (select 1 from IndexedLineItems ili where ih.Docid = ili.DocId)
Run Code Online (Sandbox Code Playgroud)

  • @Kam不,这是一个相关的子查询.连接是`ih.Docid = ili.DocId`. (2认同)