Condition

NOT (a=1 AND b=1) vs (a<>1 AND b<>1)

  • April 7, 2017

WHERESQL 查詢的子句中,我希望這兩個條件具有相同的行為:

NOT (a=1 AND b=1)

對比

a&lt;&gt;1 AND b&lt;&gt;1

第一個條件的行為符合預期,雖然我期望第二個條件做同樣的事情,但事實並非如此。

這是非常基本的東西,但很慚愧,我看不出我做錯了什麼。

它們不是等價的。

NOT (a=1 AND b=1)

相當於:

(NOT a=1 OR NOT b=1) &lt;=&gt; (a&lt;&gt;1 OR b&lt;&gt;1)

這種等價性稱為De Morgan's Law。參見例如:

https://en.wikipedia.org/wiki/De_Morgan%27s_laws

證明/證明布爾代數表達式等價性的一個很好的技術是對域使用 cte,並並排比較表達式:

with T(a) as ( values 0,1 )
  , U(a,b) as (select t1.a, t2.a as b 
              from t as t1 
              cross join t as t2
) 
select a,b
   , case when not (a=1 and b=1) then 1 else 0 end
   , case when a&lt;&gt;1 and b&lt;&gt;1 then 1 else 0 end 
from U

A           B           3           4          
----------- ----------- ----------- -----------
         0           0           1           1
         0           1           1           0
         1           0           1           0
         1           1           0           0

編輯:由於 DB2 不支持布爾數據類型,我將範例擴展為:

http://sqlfiddle.com/#!15/25e1a/19

重寫後的查詢如下所示:

with T(a) as ( values (0),(1),(null) )
  , U(a,b) as (select t1.a, t2.a as b 
               from t as t1 
               cross join t as t2
) 
select a,b
    , not (a=1 and b=1) as exp1 
    , a&lt;&gt;1 or b&lt;&gt;1 as exp2
from U;

查詢的結果是:

a       b       exp1        exp2
--------------------------------
0       0       true        true
0       1       true        true
0       (null)  true        true
1       0       true        true
1       1       false       false
1       (null)  (null)      (null)
(null)  0       true        true
(null)  1       (null)      (null)
(null)  (null)  (null)      (null)

如圖所示 exp1 和 exp2 是等價的。

你的第一個例子是說:

返回a = 1 AND b = 1之外的所有行

你的第二個例子是說:

返回a = 1b = 1之外的所有行

要使第二個查詢返回與第一個相同的查詢,您應該將您的查詢更改ANDOR

CREATE TABLE #Test (a BIT, b BIT);

INSERT INTO #Test
       ( a, b )
VALUES
       ( 0, 0 ),
       ( 1, 0 ),
       ( 0, 1 ),
       ( 1, 1 );

SELECT * FROM #Test AS t
WHERE NOT (a=1 AND b=1);

SELECT * FROM #Test AS t
WHERE (a &lt;&gt; 1 OR b &lt;&gt; 1);

這將返回以下結果

a   b
0   0
1   0
0   1

引用自:https://dba.stackexchange.com/questions/169286