为什么不在限制下选择查询不能正常执行,而是通过限制限制



我尝试从一个表中选择一些物质数据,并具有一个限制,即该材料不应存在于一个视图中。

所以,下面是我的代码。它不能正常执行。

select *
from Table A
where Table A.Material not in (select View A.material from View A)

此查询总是执行并直到随着时间的流逝。但是,如果我使用限制,则可以正常执行。

select *
from Table A
where Table A.Material in (select View A.material from View A)

要获取目标数据,我使用以下代码,并且可以使用。

select *
from Table A
where Table A.Material not in (select *
                               from Table A 
                               where Table A.Material in (select View A.material from View A)
                              )

这很奇怪,所以我的原始代码的问题在哪里?

您可能在 ViewA.material中有一些null-s。解决您的问题的另一种方法是:

select * from TableA where TableA.Material not in (select ViewA.material from ViewA where ViewA.material IS NOT NULL)

让我们假设ViewA.material具有值1、2和NULL的值。使用IN的查询等效于:

select * from TableA where Material=1 OR Material=2 OR Material=NULL

即使tablea将包含NULL的一行,条件Material=NULL也不是正确的,因为null = null是未知的(至少在SET ANSI_NULLS ON的默认和建议设置下(。但是TRUE OR unknown产生TRUE,因此此查询产生正确的结果。

使用NOT IN查询等效于:

select * from TableA where Material<>1 AND Material<>2 AND Material<>NULL

在这种情况下,TRUE AND unknown产生unknown,因此此查询永远不会返回任何结果。

这是一个不存在的问题,它确实会引起一些问题:这是第一个链接:https://explainextendended.com/2009/09/15/not-inot-inot-inot-not-exists-vs-vs-left-join-is-is-null-sql-sql-server/
这是此主题的另一个讨论:https://dba.stackexchange.com/questions/121034/best-practice-between-usis-using-left-join-oin-or-not-exists

可能是因为您使用的是视图,而不是表。该表可能有索引,而视图没有,这就是您因引擎而失去优化的地方。如果您尝试查看计划,您可能会很快看到正在发生的事情

最新更新