문제

그래서 나는 물었다 의문 오늘 아침, 나는 올바르게 표현하지 않았으므로 왜 Null이 Null/False를 줄 수 있는지에 대한 많은 응답을 얻었습니다.

나의 실제 질문은, DB Guys가 둘 다 null이 될 수있는 두 개의 열에 대한 불평등을 테스트하는 시간의 명예로운 패션은 무엇입니까? 내 질문은 이것과 정반대입니다 의문.

요구 사항은 다음과 같습니다. A와 B는 두 개의 열입니다.
a) A와 B가 모두 null이면 동일하고 거짓이 되세요
b) A와 B가 둘 다 NULL이 아닌 경우 A <> B를 반환합니다.
c) a 또는 b 중 하나가 널이면 같지 않으면 동일하지 않습니다.

도움이 되었습니까?

해결책

데이터 유형 및 열의 가능한 값에 따라 :

COALESCE(A, -1) <> COALESCE(B, -1)

트릭은 절대 데이터에 나타납니다.

다른 방법은 다음과 같습니다.

(A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL)

특정 RDBMS가 널을 처리하는 방식에 따라 문제가 될 수 있습니다. ANSI 표준에 의해, 이것은 당신이 원하는 것을 제공해야하지만 어쨌든 표준을 따르는 사람. :)

추신 - 또한 Coalesce 함수를 사용하면 열을 비교할 때 인덱스 사용이 무효화 될 수 있음을 지적해야합니다. 쿼리 계획 및 쿼리 성능을 확인하여 문제가 있는지 확인하십시오.

PPS- 방금 OMG Ponies가 Informix가 Coalesce를 지원하지 않는다고 언급 한 것을 알았습니다. 내가 믿는 ANSI 표준 기능이지만 표준에 대해 위에서 말한 내용을 봅니다 ...

다른 팁

나는 특히 테이블이 커질 것으로 예상되는 경우, 당신이 생각해 낸 표현을 개인적으로 쓸 것입니다. 함수로 열을 랩핑하면 엔진이 해당 열에있는 인덱스를 사용할 수 없도록하여 성능이 상처를 입 힙니다. 물론 작은 테이블에서는 어떤 종류의 문제가 아닐 수도 있지만, 테이블이 성장하는 경우를 대비하여 여전히 명백한 방법으로하고 싶습니다.

Informix에서 이와 같은 것을 시도해 볼 수 있습니까?

CASE
    WHEN a IS NULL AND B IS NULL THEN false 
    WHEN a IS NULL OR B IS NULL THEN true
    ELSE a <> B
END

~에서 SQL에 대한 IBM Informix 안내서 : 구문, 사례 표현식

Nulls가 어떻게 처리되는지 확인하려면 Null Checking을 위해 Informix 지원이 무엇이든 사용해야합니다. SE 버전 외에는 Coalesce를 지원하지 않지만 Decode 및 경우를 지원합니다.

WHERE COALESCE(t.a, 0) != COALESCE(t.b, 0)
WHERE DECODE(NULL, 0, t.a) != DECODE(NULL, 0, t.b)

SQL Server의 경우 사용하십시오.

WHERE ISNULL(A, '') <> ISNULL(B, '')

문제는 그게 다 a<>b (또는 a=b) 수율 NULL, 아니다 1 또는 0 하나 또는 둘 다 피연산자가 무인 상태 일 때. 이것은 중요하지 않습니다 = 케이스 NULL OR 1 ~이다 1 그리고 NULL OR 0 ~이다 NULL 같은 행동 0 a에서 선택하기 위해 WHERE 절.

넌 말할 수있다:

a<>b OR (a IS NULL)<>(b IS NULL)

그러나 어느 쪽이든 그렇게해야한다는 것은 NULL을 잘못 사용한다는 신호일 수 있으며,이 비슷한 조건을 의미하기 위해 다른 널 값이 아닌 다른 값을 사용하도록 스키마를 변경하는 것을 고려해야합니다.

예를 들어, 당신이있는 경우 person a title 열, null을 사용하여 제목이 없음을 나타냅니다. 그것은 '누락 된'데이텀이 아니라 제목이 없다는 것입니다. 따라서 빈 줄로 보관하십시오 '' 다른 빈 줄과 행복하게 비교할 수 있습니다. (빈 문자열 문제로 Oracle을 실행하지 않으면 ...)

IBM Informix Dynamic Server는 다양한 역사적 (일명 '나쁜'이유에 대한 부울에 대한 다소 독특한 견해를 가지고 있습니다. @astander가 제안한 아이디어를 적응 시키면서이 사례 표현식 'Works', 그러나 나는 '명백하지 않음'이라고 말한 것입니다 (참조 - 나는 당신이하기 전에 그것을 말했습니다!). 설정 단계 :

create table x(a int, b int);
insert into x values(null, null);
insert into x values(null, 1);
insert into x values(1, null);
insert into x values(1, 1);
insert into x values(1, 2);

SELECT 문 :

SELECT *
  FROM x
  WHERE   CASE
          WHEN a IS NULL AND b IS NULL THEN 'f'::BOOLEAN
          WHEN a IS NULL OR  b IS NULL THEN 't'::BOOLEAN
          WHEN a != b                  THEN 't'::BOOLEAN
          ELSE                              'f'::BOOLEAN
          END
;

이 쿼리의 결과는 다음과 같습니다.

                 1
      1           
      1          2

문제 :

  • ID는 거짓 또는 참 또는 미지의 키워드로 인식하지 못합니다.
  • IDS는 'a! = b'(또는 'a <> b')와 같은 부울 표현을 인식하지 못합니다.

그렇습니다. 이것을 진술 해야하는 것은 크게 고통 스럽습니다.

만약에

where ((A=B) OR (A IS NULL AND B IS NULL))

평등을위한 것입니다. 그러면 사용하지 않는 이유는 다음과 같습니다.

where NOT (
  ((A=B) OR (A IS NULL AND B IS NULL))
)

불평등을 위해?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top