我尝试从一个表中选择一些物料数据,并且有一个限制,即该物料不应存在于一个视图中。
所以,下面是我的代码。无法正常执行。
select *
from Table A
where Table A.Material not in (select View A.material from View A)
此查询始终执行并一直执行。 但是,如果我使用Restriction IN,它可以正常执行。
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)
)
这很奇怪,我的原始代码在哪里出现?
答案 0 :(得分:1)
您可能在ViewA.material
中有一些NULL。解决问题的另一种方法是:
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
,因此此查询将永远不会返回任何结果。
答案 1 :(得分:0)
这是NOT IN的问题,它确实引起一些问题:
这是第一个链接:https://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/
这是该主题的另一讨论:https://dba.stackexchange.com/questions/121034/best-practice-between-using-left-join-or-not-exists
可能是因为您使用的是VIEW,而不是TABLE。 TABLE可能有索引,而VIEW没有索引,这就是引擎失去优化的地方。如果您尝试查看plan,则可能很快就会看到发生了什么事