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


16

WHERESQL 쿼리 의 절 에서이 두 가지 조건이 동일한 동작을 갖기를 기대합니다.

NOT (a=1 AND b=1)

vs

a<>1 AND b<>1

첫 번째 조건은 예상대로 작동하며 두 번째 조건은 동일한 작업을 수행하지만 효과는 없습니다.

이것은 매우 기본적인 것들이지만, 부끄럽게도 내가 뭘 잘못하고 있는지 알 수 없습니다.


예제 데이터 및 예상 결과와 실제 결과를 게시 할 수 있습니까?
Gareth Lyons

6
그 대답 레나드 의해 명시된 바와 같이,이 드 모건 규칙의 예이다 : 하지 (A 및 B) = (되지 A) 또는 (되지 B) , 하지 (A 또는 B) = (되지 A) 및 (되지 B) . NULL 값에주의하십시오.
Barranka

2
영어로 생각하십시오. 당신의 첫 번째는 "저는 프랑스의 왕이자 인간의 경우가 아닙니다"-명백히 사실입니다. 두 번째는 "나는 프랑스의 왕도 아니고 인간도 아니다"-명백히 거짓입니다.
패트릭 스티븐스

3
이것은 "De Morgan의 법칙"과 상충됩니다. 동등한 것입니다 a <> 1 OR b<>1.
Willem Van Onsem

답변:


46

그것들은 동등하지 않습니다.

NOT (a=1 AND b=1)

다음과 같습니다.

(NOT a=1 OR NOT b=1) <=> (a<>1 OR b<>1)

이 동등성을라고합니다 De Morgan's Law. 예를 들어 :

https://ko.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<>1 and b<>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<>1 or b<>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는 동일합니다.


16
De Morgan을 언급하여 +1 모든 형태의 프로그래밍 / 스크립팅을하는 사람은 반드시 읽어야합니다.
Tonny

그러나 NULL은 어떻습니까?
dan04

@ dan04 첫 번째 줄에 NULL을 추가 할 수 있습니다 ( with T(a) as ( values 0,1,NULL )쿼리 가 되어 다시 실행되면 어떤 일이 발생하는지 알 수 있습니다. NULL은 우리가 배우는 대부분의 설정된 동등성 규칙에서 렌치를 던집니다. 짧은 대답은 a = NULL 및 a < > NULL 둘 다 NULL을 생성하므로 else의 경우에 해당합니다. 추가 정보 : ( stackoverflow.com/questions/1833949/… )
Brian J

DB2의 첫 번째 예를 왜 수정해야하는지 잘 모르겠습니다. 그것은 나와 같이 작동합니다. DB2 LUW 대신 i 용 DB2를 사용하고 있습니다. 두 번째 예에는 i 용 DB2에 대한 일부 구문 오류가 있습니다.
jmarkmurphy

@ jmarkmurphy, 나는 i 용 DB2를 모른다. 아마도 거기에서 작동한다. LUW의 경우 케이스 표현식은 0 또는 1로 맵핑되므로 널도 포함하도록 변경되어야합니다. 그렇게함으로써 사건 표현은 더 이상 사소한 것이 아니며 (IMO) 표현에 대한 추론이 어려워진다.
Lennart

9

첫 번째 예는 다음과 같습니다.

모든 행 반환을 제외한 곳에 A = 1 AND B = 1

두 번째 예는 다음과 같습니다.

모든 행 반환 을 제외한 A는 1 = OR B = 1

두 번째 검색어가 첫 번째 검색어와 동일하게 반환 AND되도록하려면OR

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 <> 1 OR b <> 1);

결과는 다음과 같습니다.

a   b
0   0
1   0
0   1

a<>1 AND b<>1"a = 1 OR b = 1"로 번역 되는지 설명 할 수 있습니까?
doub1ejack

1
@ doub1ejack, 첫 번째 문장과 동일하게 만들려면 두 번째 문장에 추가 부정이 필요합니다 NOT ( a=1 OR b=1 ). 불행한 자연 언어에는 모호성이 포함되어있어 논리 수식을 자연 언어로 변환하거나 그 반대로 변환하기가 어렵습니다. 예를 들어, 또는 neither a=1 nor b=1의미 합니까? NOT ( a=1 OR b=1 )(NOT a=1) OR (NOT b=1)
Lennart

1
@ doub1ejack "차가 빨간색이고 문이 4 개 있습니다"의 반대는 "차가 빨간색이 아니거나 문이 4 개 없습니다"입니다. 여러 가지 사실 성명을 발표 할 사실이있는 경우에, 단 하나 그들 중은 거짓 만들기 위해 거짓이어야합니다.
hobbs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.