为什么OR语句给出了我不想要的记录?

时间:2012-02-07 21:09:50

标签: sql sql-server sql-server-2005 tsql

此查询:

select dept, job
from organizations
where (dept = 'Marketing' and job <> 'Sam Wise')
or    (dept = 'Marketing' and job <> 'The Precious')

保留给予记录的工作显示'The Precious'的时候不应该。但是如果我以这种方式编写查询:

select dept, job
from organizations
where (dept = 'Marketing' and job <> 'Sam Wise')
and   (dept = 'Marketing' and job <> 'The Precious')

然后我得到了正确的记录。没有'Sam Wise'或'The Precious'的工作。所以我想知道我对T-SQL中的AND和OR的理解是否被混淆,或者我的sql服务器是不是很糟糕。

简而言之,为什么第一个查询不会删除所有将“Sam Wise”或“The Precious”作为作业的记录,但第二个查询是?

7 个答案:

答案 0 :(得分:14)

那是因为如果发现任何一个括号OR子句为真,则包含该行。你的两个条件ORed在逻辑上意味着所有行的联合,其中作业不是'Sam Wise'或NOT'The Precious'。并且所有行都符合这些标准,因为例如'Sam Wise'不是'The Precious',因此满足第二个条件。

以下是我认为您正在尝试的内容:

select dept, job
from organizations
where
   dept = 'Marketing'
   and not (
      job = 'Sam Wise'
      or job = 'The Precious'
   )

请注意,您只需使用AND:

select dept, job
from organizations
where
   dept = 'Marketing'
   and job <> 'Sam Wise'
   and job <> 'The Precious'

这是逻辑法的一个很好的例子。要表示相同的条件(A = X OR B = Y)但是表达消极(您希望前面不是),始终会转换为NOT (A <> X AND B <> Y)。它与(A = X AND B = Y) =&gt;的作用相同NOT (A <> X OR B <> Y)。在您的情况下,AB是相同的,因此job上的查询条件等同于NOT (A = X AND A = Y),有些人认为这将始终返回true { {1}}永远不会成真。

由于IN()可以用来表达许多OR条件,你可以用这种方式简化查询:(虽然不是引擎必须做的工作,但是相同)。

A = X AND A = Y

稍后我意识到select dept, job from organizations where dept = 'Marketing' and job not in ('Sam Wise', 'The Precious') =&gt;的翻译A = X只是否定,在单词的特殊查询意义上。在最简单的形式中,逻辑定律就是这样,给出了两个命题P1和P2:

  • A <> X =&gt; NOT (P1 AND P2)
  • (NOT P1 OR NOT P2) =&gt; NOT (P1 OR P2)

请注意,这些也适用:

  • (NOT P1 AND NOT P2) =&gt; (P1 AND P2)
  • NOT (NOT P1 OR NOT P2) =&gt; (P1 OR P2)

这些转换也非常有用。

答案 1 :(得分:9)

这两个条款是独立考虑的。也许试试:

WHERE dept = 'Marketing' AND job NOT IN ('Sam Wise', 'The Precious');

答案 2 :(得分:4)

这就是OR的工作原理,如果至少有一部分为真,它将返回true。 让我们看看第一个查询如何适用于Job =='Sam Wise'的行。

(dept = 'Marketing' and 'Sam Wise' <> 'Sam Wise') -- FALSE
OR    
(dept = 'Marketing' and 'Sam Wise' <> 'The Precious') -- TRUE

我们得到FALSE OR TRUE所以整个WHERE都返回TRUE。如果两个部分都为TRUE,则AND返回TRUE,这就是第二个查询返回预期结果的原因。

答案 3 :(得分:3)

第一组规则匹配“The Precious”,第二组规则匹配“Sam Wise”

换句话说,dept = 'Marketing' AND job <> 'Sam Wise'对于dept = 'Marketing' and job = 'The Precious'的行是正确的,因此选择了该行。同样,对于dept = 'Marketing' AND job <> 'The Precious'的行,dept = 'Marketing' and job = 'Sam Wise'也适用,因此也会选择该行。

更好的查询是这样的:

SELECT dept, job
FROM organizations
WHERE
   dept = 'Marketing'
   and job <> 'Sam Wise'
   and job <> 'The Precious'

答案 4 :(得分:3)

假设您已经获得了营销部门的Sam Wise工作记录。

它如此评估:

(dept = 'Marketing' and job <> 'Sam Wise') 
OR (dept = 'Marketing' and job <> 'The Precious')

(TRUE and FALSE) 
OR (TRUE and TRUE)

(FALSE)
OR (TRUE)

(TRUE)

因此包含该文件。同样的事情,如果它是珍贵的。您的第一个查询基本上只是确保它适用于营销部门。

答案 5 :(得分:2)

select语句的一部分:

where (dept = 'Marketing' and job <> 'Sam Wise')
or    (dept = 'Marketing' and job <> 'The Precious')

表示如果一个或另一个为真,它将返回查询,或两者都返回。这就是为什么你会得到不想要的结果。

statement1 = true OR statemet2 = true ...result true
statement1 = false OR statemet2 = true ...result true
statement1 = true OR statemet2 = false...result true
statement1 = false OR statemet2 = false ...result false

只有当两个语句都为真时,使用AND才会返回true:

statement1 = true AND statemet2 = true ...result true
statement1 = false AND statemet2 = true ...result false
statement1 = true AND statemet2 = false...result false
statement1 = false AND statemet2 = false ...result false

答案 6 :(得分:1)

这个概念适用于数学和逻辑,并不是严格意义上的编码。它只是AND和OR在逻辑方面的工作方式。