【问题标题】:Using T-SQL EXCEPT with DELETE / Optimizing a query使用带有 DELETE 的 T-SQL EXCEPT / 优化查询
【发布时间】:2017-03-31 14:39:05
【问题描述】:

以下代码从表中删除与非活动项目相关的任务记录。

delete from [Deliverables] where 
[Deliverables].[ProjectID] not in 
(
select 
[ProjectID] from [ActiveProjects]
)

我在某处读到,将NOT IN 与返回大量值的子查询一起使用并不是最有效的做法,最好使用EXCEPT 子句。

但是,当我尝试使用以下代码时,出现错误(关键字“except”附近的语法不正确。)

delete from [Deliverables]
except
select * from [Deliverables], [ActiveProjects]
where [Deliverables].[ProjectID] = [ActiveProjects].[ProjectID]

如何将EXCEPTDELETE 一起使用?如果我不能,有什么方法可以优化我的查询以更快地执行?

【问题讨论】:

    标签: sql sql-server-2008 tsql query-optimization


    【解决方案1】:

    您也可以尝试not exists,脚本如下所示:

    delete from [Deliverables] 
    where not exists 
        (select 1 
            from [ActiveProjects]
            where [ActiveProjects].[ProjectID] = [Deliverables].[ProjectID])
    

    如果[ActiveProjects]中有很多数据,那应该是更好的解决方案,但是它是所有数据依赖的,所以请在使用前测试效率。

    【讨论】:

    • 这个解决方案对我有用,它比使用 NOT IN 子句要快得多。谢谢!
    • 这是一个不错的解决方案(我赞成),但并没有真正回答有关 EXISTS 部分的问题。 EXISTS 与 SELECT 语句一起使用。将它与 DELETE 一起使用的唯一方法是,如果您还按照其他解决方案中所示的方式执行 JOIN(这是我试图避免的)。另见:stackoverflow.com/q/55423803/2949093
    【解决方案2】:

    像这样尝试(通过添加 where 子句和列名等来修改您的需要)

    delete from table1
      from table1 a
     inner join
          ( select your_column
              from table1
            except
            select your_column
              from table2
          ) b
        on a.your_column = b.your_column;
    

    【讨论】:

      【解决方案3】:
      delete d
      from [Deliverables] as d
          inner join (
              select d2.[ProjectId] from [Deliverables] as d2
              EXCEPT
              select ap.[ProjectId] from [ActiveProjects] as ap
          } as todel on
              ((todel.[ProjectId] is NULL) and (d.[ProjectId] is NULL))
              or todel.[ProjectId] = d.[ProjectId]
      

      一个微妙之处:关于 EXCEPT 的好处是它将等同于 NULL 值,而不是决定它们永远不匹配(就像“=”那样)。在您的简单示例(仅查看 id)中,这不太可能有价值,但是如果您正在比较允许空值的表的较大部分,您将不得不考虑这种尴尬的“空匹配”或错过很多行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多