我有一张这样的表。
NoteID CustomerID CustomerName Note Type Date Active
6 81 Paris test Info 2015-06-04 1
10 81 Rotterdam Everything is allright Comment 2015-06-04 1
11 81 Hamburg Everything is allright Info 2015-06-04 1
12 81 Hamburg Everything is allright Info 2015-06-04 1
13 81 Amsterdam Everything is allright Info 2015-06-04 1
14 81 Rotterdam Everything is allLeft Comment 2015-06-04 1
15 81 Hamburg Everything is allLeft Info 2015-06-04 1
16 81 Hamburg Everything is allLeft Info 2015-06-04 1
17 81 Amsterdam Everything is allLeft Info 2015-06-04 1
当我执行此查询时:
SELECT *
FROM CarsNote
WHERE Note LIKE '%ddddddddddddddd%'
AND Type != 'Comment'
OR Type != 'error'
结果中包含所有注释。
我的期望是结果中没有注释。由于LIKE
声明'%ddddddddddddddd%'
。
有人可以解释为什么这个查询没有像我预期的那样工作吗?
答案 0 :(得分:13)
不确定。它被称为运算符优先级(或更一般地,运算符评估顺序)。
如果您添加括号,这就是您正在评估的内容:
WHERE ((Note LIKE '%ddddddddddddddd%') AND Type != 'Comment') OR Type != 'error'
根据MSDN:
当在语句中使用多个逻辑运算符时,首先计算NOT,然后计算AND,最后计算OR。算术运算符和按位运算符在逻辑运算符之前处理。
NOT
部分很棒 - 这意味着你可以摆脱不必要的括号。其余的更复杂一点 - AND
将始终优先于OR
,其他条件相同。这也意味着蒂姆的第二个建议实际上会起作用 - 但是,不,不要这样做。这太疯狂了。
即使你知道操作员评估的规则,也不要明白它是一个坏主意 - 它太脆弱了,更不用说难以阅读了(我' m目前使用的代码库充满了这样的东西 - 只是不要。你将来会为自己和其他所有人节省很多麻烦。)只需使用它:
where Note like '%ddddddddddddddd%' or not (Type = 'Comment' or Type = 'Error')
甚至更好,
where Note like '%ddddddddddddddd%' and Type not in ('Comment', 'Error')
答案 1 :(得分:7)
您有两种选择:
OR
包裹在paranthesis AND
+ OR
第一种方法(*):
SELECT *
FROM CarsNote
WHERE Note LIKE '%ddddddddddddddd%'
AND (Type != 'Comment' OR Type != 'error')
第二
SELECT *
FROM CarsNote
WHERE Note LIKE '%ddddddddddddddd%' AND Type != 'Comment'
OR Note LIKE '%ddddddddddddddd%' AND Type != 'error'
我更喜欢第一个,因为它更简洁,更不容易出错。
*重要说明:两种方法都没有意义,因为!=
和OR
的组合始终为true,它会删除过滤器并返回所有记录。实际上你必须使用AND
:
WHERE Note LIKE '%ddddddddddddddd%'
AND (Type != 'Comment' AND Type != 'error')
您不需要使用AND
:
WHERE Note LIKE '%ddddddddddddddd%'
AND Type != 'Comment' AND Type != 'error'
如果您想要包含/排除多个值,使用IN
/ NOT IN
会更具可读性:
WHERE Note LIKE '%ddddddddddddddd%'
AND Type NOT IN('Comment', 'error')
请注意,这会跳过Type
为NULL
的记录。因此你必须使用:
WHERE Note LIKE '%ddddddddddddddd%'
AND (Type IS NULL OR Type NOT IN('Comment', 'error'))
答案 2 :(得分:3)
组合时始终使用parantheses:
function Person() {}
Person.prototype.Name = "";
Person.prototype.Lastname = "";
var NewPerson= new Person();
NewPerson.Name = "Nancy";
NewPerson.Lastname = "Drew"; //<--- right way
NewPerson.lastname = "Drew"; //<--- wrong property
或您还可以使用SELECT *
FROM CarsNote
WHERE Note LIKE '%ddddddddddddddd%'
AND (Type != 'Comment'
OR Type != 'error')
:
NOT IN
答案 3 :(得分:3)
您对此SQL的评论是:
使用d ... d等注释向我显示所有记录,而不是“注释”或类型,其中类型不是“错误”
在 OR之前执行AND语句。它可以写成:
(Note LIKE '%ddddddddddddddd%' AND Type != 'Comment') OR Type != 'error'
我猜您需要的是:
Note Like '%ddddddddddddddd%' AND (Type != 'Comment' OR Type != 'error')
答案 4 :(得分:2)
在下面的代码段中添加我提到的括号。 OR导致了这种情况,因为没有类型是=&#39;错误&#39;
SELECT *
FROM CarsNote
WHERE Note LIKE '%ddddddddddddddd%'
AND (Type != 'Comment'
OR Type != 'error')
答案 5 :(得分:0)
尝试始终在where子句上使用括号来显式设置顺序。 我认为这是最好的做法。