Sql server SQL中的WHERE子句忽略或

Sql server SQL中的WHERE子句忽略或,sql-server,tsql,Sql Server,Tsql,我有一个存储过程,它正在计算我拥有的未完成1000或取消1100的文档数。当我只有其中一个条件时,它会正确地计算数字,但一旦我添加了or,它就会忽略任何逻辑而简单地获取所有内容。在这里,SQL肯定缺少一些基本的东西 SELECT [PartnerCoId] as DisplayID ,[PartnerCompanyName] as DisplayName ,Count(*) as DocumentTotal FROM vwDocuments

我有一个存储过程,它正在计算我拥有的未完成1000或取消1100的文档数。当我只有其中一个条件时,它会正确地计算数字,但一旦我添加了or,它就会忽略任何逻辑而简单地获取所有内容。在这里,SQL肯定缺少一些基本的东西

    SELECT 
       [PartnerCoId] as DisplayID
      ,[PartnerCompanyName] as DisplayName
      ,Count(*) as DocumentTotal
  FROM vwDocuments 
  where coid = @inputCoid and DocumentType = 'order' 
  and Status <> 1100 
  and PartnerCoId <> @inputCoid
  group by 
        [PartnerCoId]
       ,[PartnerCompanyName]
union all
SELECT [CoId] as DisplayID
      ,[CompanyName] as DisplayName      
      ,Count(*) as DocumentTotal
  FROM vwDocuments 
  where PartnerCoId = @inputCoid and DocumentType = 'order' 
  and Status <> 1100 
  and CoId <> @inputCoid
  group by [CoId]
      ,[CompanyName]            
    order by [DisplayName]
这将返回未处于取消状态的文档数。如果我将1100更改为1000,它将返回未处于完整状态的文档数。一旦我将查询更新为:

and (Status <> 1100 or Status <> 1000)
这打破了逻辑


想法?我已经尝试了许多不同的查询逻辑组合,但无法解决这个问题。

如果我理解正确,您希望所有状态都不是1100或1000

如果是,那么您需要:

and (Status <> 1100 and Status <> 1000)

如果使用or,则状态1100将通过测试,因为它是1000。

与其纠结于布尔逻辑,不如使用not in:


它更容易阅读和理解,因为它实际上是英文的,而且因为它都在一个语句中,所以你也不需要括号。

我认为你的逻辑可能有点不正确。说“未完成”或“未取消”将返回所有文档,因为所有行都符合此条件

获取状态为1100的文档。这将在查询中返回,因为它在OR语句的一半上计算为TRUE

试着把那条线换成

AND Status NOT IN (1000,1100)

这应该只返回未完成或取消的文档。希望这有帮助

让我们简化并思考一下您的逻辑

DECLARE @i INT = 1;

IF (@i <> 1 OR @i <> 2)
  PRINT 'true';
ELSE
  PRINT 'false';
你能为@i提供一个生成false的值吗?我想不出一个。想想看:

如果@i=1,那么@i1为假,而@i2为真。因为只有其中一个条件为真,整个条件才为真,所以结果为真。 如果@i=2,那么@i1为真,而@i2为假。因为只有其中一个条件为真,整个条件才为真,所以结果为真。 如果@i是1和2之外的任何其他值,则这两个条件都为真。
正如其他答案所表明的,解决这个问题的方法是更改或to AND,或使用NOT IN,尽管我不太喜欢NOT IN,因为当您检查一列时,该列可以为null,-我更喜欢一致编程,而不是必须知道某个东西的工作情况和它真正工作的情况,确实没有。

您是否尝试将其更改为AND?如果你想让每件事都不等于这两件事,那么它应该是和。是的,这将是那样的一天,谢谢你。这是一种非常优雅的方式,谢谢你的洞察力。
DECLARE @i INT = 1;

IF (@i <> 1 OR @i <> 2)
  PRINT 'true';
ELSE
  PRINT 'false';