SQL Server에서 NULL = NULL이 false로 평가되는 이유


146

SQL Server nullParam=NULL에서 where 절이 있으면 항상 false로 평가됩니다. 이것은 직관적이지 않으며 많은 오류를 일으켰습니다. 키워드 IS NULLIS NOT NULL키워드가 올바른 방법임을 이해합니다 . 그러나 왜 SQL 서버가 이런 식으로 작동합니까?


166
나는 언니도없고 친구도 없다. "NULL = NULL"이면 공통 자매가 있으므로 관련이 있습니다! :)
Matt Hamilton

11
SQL NULL에 대한 논란이 오래 지속됩니다 (예 : en.wikipedia.org/wiki/Null_%28SQL%29#Controversy and firstsql.com/inulls.htm 참조 ). 여기서의 요점은 평등은 오랫동안 확립 된 수학적 개념이고 SQL이 그것을 위반한다는 것입니다. 평등은 재귀 적입니다. 그것은 항상 사실이어야합니다. 그렇지 않으면 표준이 아닌 평등에 대한 해석을 도입하고 있으며 혼란은 명백한 결과입니다.
MaD70 2009

14
수학을 전혀 위반하지 않습니다. 두 가지 숫자를 생각하고 있습니다. 나는 그들이 무엇인지 말하지 않을 것입니다. 자 이제 말해봐, 그들이 평등합니까?
Tom H

10
@ 매트, 나는 당신의 비유에 동의하지 않습니다. NULL = NULL은 당신이 공통 언니를 의미하는 것이 아니며, 둘 다 언니가 없다는 것을 의미합니다.
reustmd 2016 년

5
@ manu08 아니요, 현재 구현 (NULL은 NULL과 절대 같지 않습니다)은 우리에게 자매가 부족하다는 것을 의미합니다.
Matt Hamilton

답변:


205

이 경우 널을 "알 수 없음"으로 생각하십시오 (또는 "존재하지 않음"). 두 경우 중 하나의 가치를 알지 못하기 때문에 둘이 같다고 말할 수 없습니다. 따라서 null = null은 값이 같은지 알 수 없으므로 시스템에 따라 false 또는 null이 아닌 것으로 평가됩니다 (시스템에 따라 false 또는 null). 이 동작은 ANSI SQL-92 표준에 정의되어 있습니다.

편집 : 이것은 ansi_nulls 설정 에 따라 다릅니다 . ANSI_NULLS가 꺼져 있으면이 값은 true로 평가됩니다. 예를 들어 다음 코드를 실행하십시오 ...

set ansi_nulls off

if null = null
    print 'true'
else
    print 'false'


set ansi_nulls ON

if null = null
    print 'true'
else
    print 'false'

11
x = x는 x가 알려진 값일 때만 참 입니다. NULL은 알 수없는 값 의 텍스트 표현입니다 . 두 개의 알 수없는 값이 있으면 그 동등성에 대해 결론을 내릴 수 없습니다. 나는 몇 세기 동안 진실을 유지했다고 믿습니다.
Dewayne Christensen

4
12 월 이후 계절별 예제를 사용해 보겠습니다. 나무 아래에 두 개의 선물이 있습니다. 자, 내가 똑같은 것을 얻었는지 말 해주세요.
Dewayne Christensen

5
SQL NULL은 IEEE 부동 소수점 NaN과 다르지 (NaN == NaN) == false && (NaN != Nan) == false && (NaN < NaN) == false && ...않습니다. 숫자가 아닌 경우에는 그것에 대해 많이 말할 수 없기 때문입니다. 그것은 알려지지 않은 것입니다. 전에 본 적이없는 사람들에게는 직관적이지 않더라도 개념은 건전합니다.
Pavel Minaev

8
여기서 NULL은 값 집합 (관계형 용어에서 도메인)의 구성원이 아니기 때문에 반사성을 위반하지 않습니다. NULL 은 값이 아닙니다 . 값을 알 수없는 자리 표시 자입니다.
Pavel Minaev

9
다시 말해, NULLSQL 표현식의 모든 것을 고유 한 수학적 변수 로 취급 할 수 있습니다 . 따라서 표현식 NULL = NULL은로 x = y, 여기서 x그리고 y바인딩되지 않은 변수 로 취급해야 합니다. 누군가가 당신에게 묻는다면, 그 가치는 x = y무엇입니까? 합리적인 답변은 "일부 z"입니다. 그래서 우리는 (x = y) = z그것을 SQL로 다시 번역합니다 (NULL = NULL) = NULL.
Pavel Minaev

130

프랭크는 몇 살입니까? 모르겠습니다 (널).

셜리는 몇 살입니까? 모르겠습니다 (널).

Frank와 Shirley는 같은 나이입니까?

Frank와 Shirley 같은 나이 일 있기 때문에 정답은 "모름"이 아니라 "아니오" 여야합니다. 우리는 단순히 모릅니다.


4
null이 "알 수 없음"을 의미한다는 데 동의하지 않습니다. 실제로 의미하는 것은 "데이터 없음"입니다. 정보가 알려지지 않은 경우를 나타내는 데 사용될 수 있지만 실제로는 존재하지 않는 것을 나타내는 데 사용될 가능성이 높습니다. 예를 계속하려면 : Frank의 중간 이름은 무엇입니까? 그는 하나도 없습니다 (널). 셜리의 중간 이름은 무엇입니까? 그녀는 하나도 없습니다 (널). Frank와 Shirley는 같은 중간 이름을 가지고 있습니까? 예? 아니? 몰라? 나는 "아니오"에 대한 논쟁을 볼 수 있고, "모르지 않는다"에 대한 논쟁을 볼 수 있지만 지나치게 문자 적이 지 않으면 "예"에 대한 실제 논쟁은 없습니다.
Richiban

2
@richiban 동의하지 않습니다. 행의 존재가 없다는 것은 '데이터 없음'을 의미합니다
Neil McGuigan

1
@NeilMcGuigan 자체 테이블이있는 데이터의 경우 열에 표시되는 데이터는 어떻습니까? 데이터가 존재하지 않는다는 사실을 나타 내기 위해 'null'을 사용하지 않습니까? '알 수 없음'은 데이터가없는 매우 구체적인 이유입니다.
Richiban

3
그러나 null = null수확량 FALSE은 아닙니다 NULL.
slartidan 2016 년

1
@slartidan 나는 당신에 동의하지만, 그것은 잘못입니다
Neil McGuigan

28

여기 내 희망을 분명히 밝힐 것입니다.

NULL = NULL에 평가는 FALSE잘못된 것입니다. 해커와 미스터가 올바르게 대답했습니다 NULL. 이유는 다음과 같습니다. Dewayne Christensen은 Scott Ivey 에 대한 의견으로 저에게 썼습니다. .

12 월 이후 계절별 예제를 사용해 보겠습니다. 나무 밑에 선물이 두 개 있습니다. 자, 내가 똑같은 것을 얻었는지 말 해주세요.

그것들은 다를 수도 있고 같을 수도 있습니다 . 둘 다 선물을 열 때까지 알 수 없습니다 . 누가 알아? 서로를 모르고 둘 다 같은 선물을 한 두 사람을 초대했습니다. 드물지만 불가능하지는 않습니다. § .

질문 :이 두 알 수없는 동일한 (=, 같음)을 제시합니까? 정답은 다음과 같습니다. UNKNOWNNULL 입니다.

이 예는 보여주기 위해 의도 된 그 ".. ( false또는 null, 시스템에 따라하는) ..."정답입니다 - 그것은하지 않습니다 NULL 3VL 정확합니다 (또는 오답을주는 시스템을 수락해도 괜찮습니까? )

이 질문에 대한 정답 은 다음 두 가지 을 강조해야합니다.

  • 3 값 논리 (3VL)는 직관적이지 않습니다 (스택 오버플로 및 기타 포럼에서이 주제에 대한 수많은 다른 질문을 참조하십시오).
  • SQL 기반 DBMS는 종종 3VL조차도 존중하지 않으며 때로는 잘못된 답변을 제공합니다 (원래 포스터가 주장하는 것처럼 SQL Server는이 경우).

그래서 나는 반복한다 : SQL은 평등의 재귀 속성을 해석하도록 강요하지 않는다.

for any x, x = x §§ (일반 영어 : 담론의 세계가 무엇이든 "사물"은 항상 자신과 같습니다 ).

3VL에서의 .. ( TRUE, FALSE, NULL). 사람들의 기대는 2VL ( TRUE,, FALSE심지어 SQL에서도 다른 모든 값에 유효합니다)을 준수 x = x 합니다. TRUE 예외없이 - X의 가능한 값.

또한 NULL은 " 관계 변수의 일부로 속성 값 (??)으로 할당 할 수 값이 아닌 "(죄 학자가 주장하는 것처럼)입니다. 따라서 논리 표현식 유형뿐만 아니라 모든 유형 (도메인)에 허용되는 값입니다.

그리고 이것은 내 요점이었다 . NULL가치로서 "이상한 짐승"이다. 완곡 성이 없다면 나는 말하기를 선호한다. 말도 안된다. .

이 공식은 훨씬 명확하고 논쟁의 여지가 없다고 생각합니다. 저의 영어 실력이 유감입니다.

이것은 NULL 문제 중 하나 일뿐 입니다. 가능하면 완전히 피하는 것이 좋습니다.

§ 우리는 가치 에 대해 염려 한다 여기서 하므로 두 선물이 항상 두 개의 다른 물리적 대상이라는 사실은 유효한 반대가 아닙니다. 당신이 내가 미안하다고 확신하지 않는다면, 이것이 가치와 "객체"의미의 차이점을 설명하는 곳이 아닙니다 (관계 대수는 처음부터 가치 의미가 있습니다-Codd의 정보 원리 참조; 일부 SQL DBMS 구현자는 공통 의미론조차 신경 쓰지 않습니다).

§§ 내 지식에 따르면, 이것은 고대부터 인정 된 공리 (형태 또는 다른 형태이지만 항상 2VL로 해석 됨)입니다. 정확히 그렇게 직관적이기 때문입니다. 3VL (실제로 논리 계열)은 훨씬 최근의 개발이지만 처음 개발 된시기는 확실하지 않습니다.

참고 : 누군가가 Bottom , Unit SQL NULL을 정당화하기 위해 Option Types를 NULL을 사용한 SQL 구현에 사운드 유형 시스템이 어떻게 있는지를 보여주는 매우 상세한 검사 후에 만 ​​확신 할 것입니다. NULL (이것들은 "quite-not-quite-values")이 실제로 무엇인가.


다음에 나는 몇몇 저자들을 인용 할 것이다. 모든 오류 또는 누락은 아마도 원저자에 의한 것이 아니라 내 것입니다.

SQL NULL의 Joe Celko

Joe Celko가이 포럼에서 자주 인용 한 것을 보았습니다. 분명히 그는 여기에서 존경받는 작가입니다. "나는 그가 SQL NULL에 대해 무엇을 썼는가? NULL에 수많은 문제를 어떻게 설명 하는가?" 내 친구 중 하나의 전자 책 버전이 있습니다 스마트 폰을위한 Joe Celko의 SQL : 고급 SQL 프로그래밍, 3 판을 가지고 있습니다. 보자

먼저 목차. 가장 많이 눈에 띄는 것은 NULL이 언급 된 횟수와 가장 다양한 상황입니다.

3.4 산술 및 NULL 109
3.5 NULL로 값 변환 및 NULL 110
3.5.1 NULLIF () 함수 110
6 NULL : SQL 185에서 데이터 누락
6.4 NULL 비교 190
6.5 NULL 및 논리 190
6.5.1 하위 쿼리 조건 자에서 NULL 191
6.5.2 표준 SQL 솔루션 193
6.6 수학 및 NULL 193
6.7 함수 및 NULL 193
6.8 NULL 및 호스트 언어 194
6.9 NULL에 대한 설계 조언 195
6.9.1 호스트 프로그램에서 NULL 방지 197
6.10 다중 NULL 값에 대한 참고 사항 198
10.1 IS NULL 조건 자 241
10.1. 1 NULL 소스 242
...

등등. 나에게 "불쾌한 특별한 경우"를 울린다.

나는이 책에서 발췌 한 일부 사례에 대해 저작권의 이유로 본질적인 것으로 제한하려고 노력할 것이다. 나는이 인용문들이 "공정한 사용"교리에 속한다고 생각하며 책을 사도록 자극 할 수도있다. 그래서 아무도 불평하지 않기를 바란다. 또한 동일한 이유로 코드 스 니펫보고를 삼가야합니다. 미안합니다. 데이터에 근거한 추론에 대해 읽으려면 책을 구입하십시오.

다음에 나오는 괄호 안의 페이지 번호입니다.

NOT NULL 제약 조건 (11)

가장 중요한 열 제약 조건은 NOT NULL로, 열에서 NULL 사용을 금지합니다. 이 제한 조건을 일상적으로 사용하고 정당한 이유가있는 경우에만 제거하십시오. 데이터에 대해 쿼리 할 때 NULL 값 의 합병증을 피하는 데 도움이됩니다 .

값이 아닙니다 . 값이 갈 수있는 장소를 보유하는 마커입니다.

다시 말하지만이 "값은 아니지만 값"은 의미가 없습니다. 나머지는 나에게 현명 해 보인다.

(12)

요컨대, NULL은 SQL에서 많은 불규칙한 기능을 유발하므로 나중에 설명하겠습니다. 가장 좋은 방법은 상황과 피할 수없는 NULL 규칙을 외우는 것입니다.

SQL, NULL 및 무한의 제안 :

제 3 장 : SQL의 숫자 데이터

SQL은 여러 가지 이유로 수학에 대한 IEEE 모델을 승인하지 않았습니다.

...

수학에 대한 IEEE 규칙이 SQL에서 허용 된 경우 무한에 대한 유형 변환 규칙과 변환 후 무한 정확한 숫자 값을 나타내는 방법이 필요합니다. 사람들은 NULL에 충분한 문제가 있으므로 거기에 가지 마십시오.

특정 컨텍스트에서 NULL이 실제로 의미하는 바에 따라 SQL 구현이 결정되지 않았습니다.

3.6.2 지수 함수 (116)

문제는 (x <= 0) 일 때 로그가 정의되지 않는다는 것입니다. 일부 SQL 구현 은 오류 메시지를 리턴하고 일부는 NULL 및 DB2 / 400을 리턴합니다 . 버전 3 릴리스 1은 결과로 * NEGINF ( "음의 무한대"의 약자)를 리턴했습니다.

Joe Celko는 David McGoveran과 CJ Date를 인용했습니다.

6 개의 NULL : SQL에서 데이터 누락 (185)

David McGoveran과 CJ Date는 자신의 Sybase 및 SQL Server에 대한 안내서에서 “현재 SQL에 정의되고 구현 된 것처럼 NULL보다이 작가의 견해는 가치보다 훨씬 더 많은 문제이며 피해야합니다. 그것들은 매우 이상하고 일관성이없는 행동을 나타내며 풍부한 오류와 혼란의 원인이 될 수 있습니다. (이러한 의견과 비판은 SQL Server뿐만 아니라 SQL 스타일 NULL을 지원하는 모든 시스템에 적용됩니다. "

약물 중독 으로서의 NULL :

(186/187)

이 책의 나머지 부분에서, 나는 당신에게 그것들을 사용하지 말 것을 요구할 것입니다. 약물로 NULL을 생각하십시오. 올바르게 사용하면 효과가 있지만 남용하면 모든 것을 망칠 수 있습니다. 최선의 정책은 가능한 한 NULL을 피하고 필요할 때 적절하게 사용하는 것입니다.

여기에서의 저의 독특한 반대는 "적절하게 사용"하는 것인데, 이는 특정 구현 행동과 심하게 상호 작용합니다.

6.5.1 하위 쿼리 조건 자에서의 NULLS (191/192)

하위 쿼리는 종종 NULL과의 비교를 숨기는 것을 잊습니다. 다음 두 테이블을 고려하십시오.

...

결과는 비어 있습니다. 이것은 반 직관적 이지만 정확합니다.

(분리 기호)

6.5.2 표준 SQL 솔루션 (193)

SQL-92는 새로운 형식의 술어를 추가하여 3VL (3 값 논리) 문제 중 일부를 해결했습니다.

<검색 조건> IS [NOT] TRUE | 거짓 | 알 수 없는

그러나 UNKNOWN은 그 자체로 문제의 원인이되므로 아래에 인용 된 CJ Date는 4.5 장에서 권장됩니다 . SQL에서 Null 피하기 :

  • 어떤 상황에서도 키워드 UNKNOWN을 사용하지 마십시오.

UNKNOWN에서 "ASIDE" 를 읽으십시오 ( 아래 링크도 참조).

6.8 NULL과 호스트 언어 (194)

그러나 널 (NULL)이 호스트 프로그램으로 전달 될 때 널이 처리되는 방식을 알아야합니다. 임베드가 정의 된 표준 호스트 언어는 NULL을 지원하지 않으므로 데이터베이스 스키마에서 NULL을 사용하지 않는 것이 좋습니다.

(분리 기호)

6.9 NULL에 대한 설계 조언 (195)

가능하면 모든 열에 NOT NULL 제약 조건을 사용하여 모든 기본 테이블을 선언하는 것이 좋습니다. NULL은 SQL을 모르는 사람들을 혼란스럽게하며 NULL은 비쌉니다.

이의 제기 : NULL은 SQL을 잘 아는 사람들도 혼동합니다 (아래 참조).

(195)

FOREIGN KEY에서는 NULL을 피해야합니다. SQL은 이러한“의심의 이점”관계를 허용하지만 조인과 관련된 쿼리에서 정보가 손실 될 수 있습니다. 예를 들어 Orders 테이블에서 FOREIGN KEY로 참조되는 Inventory의 부품 번호 코드가 제공되면 NULL이있는 부품 목록을 가져 오는 데 문제가 있습니다. 이것은 필수 관계입니다. 존재하지 않는 부품은 주문할 수 없습니다.

(분리 기호)

6.9.1 호스트 프로그램에서 NULL 피하기 (197)

일부 프로그래밍 규칙을 사용하여 호스트 프로그램에서 데이터베이스에 NULL을 넣지 않도록 할 수 있습니다.

...

  1. 누락 된 데이터가 프로그래밍 및보고에 미치는 영향 확인 : 집계 함수를 사용하는 쿼리는 잘못된 결과를 제공 할 수 있으므로 NULL이있는 숫자 열은 문제가됩니다.

(분리 기호)

(227)

빈 세트의 SUM ()은 항상 NULL입니다. 이 트릭을 사용할 때 발생하는 가장 일반적인 프로그래밍 오류 중 하나는 둘 이상의 행을 반환 할 수있는 쿼리를 작성하는 것입니다. 당신이 그것에 대해 생각하지 않았다면, 당신은 마지막 예제를 다음과 같이 썼을 것입니다 : ...

(분리 기호)

10.1.1 NULL 소스 (242)

NULL이 발생할 수있는 위치를 기억하는 것이 중요합니다. 그것들은 열에서 가능한 값 이상의 것 입니다. 빈 세트, OUTER JOIN, NULL이있는 산술 표현식 및 OLAP 연산자의 집계 함수는 모두 NULL을 반환합니다. 이러한 구성은 종종 VIEW에서 열로 표시됩니다.

(분리 기호)

(301)

IN 술어를 EXISTS 술어로 변환하려고 할 때 널 (NULL)에 대한 다른 문제점이 있습니다.

(분리 기호)

16.3 ALL 술어 및 극단 함수 (313)

처음에이 두 술어가 SQL에서 동일하지 않다는 것은 직관적이지 않습니다.

...

그러나 극단 함수에 대한 규칙을 기억해야합니다. 더 크거나 가장 작은 값을 반환하기 전에 모든 NULL을 제거합니다. ALL 술어는 NULL을 삭제하지 않으므로 결과에서 얻을 수 있습니다.

(분리 기호)

(315)

그러나 표준의 정의는 음수로 표시되므로 NULL은 의심의 이점을 얻습니다. ...

보시다시피 UNIQUE 제약 조건에서 NULL을 피하는 것이 좋습니다.

GROUP BY 논의 :

NULL은 모두 서로 같은 것으로 취급되며 자체 그룹을 형성합니다. 그런 다음 각 그룹은 이전 결과를 대체하는 새 결과 테이블에서 단일 행으로 줄어 듭니다.

이는 GROUP BY 절의 경우 NULL = NULL은 3VL에서와 같이 NULL로 평가되지 않지만 TRUE로 평가됨을 의미합니다.

SQL 표준은 혼란 스럽습니다.

ORDER BY 및 NULL (329)

NULL 인 정렬 키 값이 NULL이 아닌 값보다 크거나 작은 것으로 간주되는지 여부는 구현에서 정의되지만 ...

... 어느 쪽이든 SQL 제품이 있습니다.

1999 년 3 월 Chris Farrar는 개발자 중 한 사람에게 질문을 제기하여 내가 이해했다고 생각한 SQL 표준의 일부 를 조사하게되었습니다 . Chris 는 본 명세서의 일반적인 이해와 실제 표현 사이에 약간의 차이점을 발견 했습니다 .

등등. Celko로는 충분하다고 생각합니다.

SQL NULL에 대한 CJ 날짜

CJ Date는 NULL에 대해 더 급진적입니다. SQL에서 NULL을 피하십시오. 사실, 그의 SQL 및 관계 이론의 4 장 : 정확한 SQL 코드 작성 방법 은 제목이 "4.4 Null에 무엇이 잘못 되었습니까?" 라는 제목의 "NO DUPLICATES, NO NULLS "입니다. 및 "4.5 SQL에서 Null 사용 방지"(링크를 따르십시오. Google 도서 덕분에 일부 페이지를 온라인으로 읽을 수 있습니다).

SQL NULL에 대한 Fabian Pascal

데이터베이스 관리실제 문제-사고 실무자를위한 참고 자료 (발췌 없음, 죄송합니다) :

10.3 실질적 의미

10.3.1 SQL NULL

... SQL은 많은 단점, 복잡성, 반 직관성 및 명백한 오류뿐만 아니라 3VL 고유의 문제로 인해 어려움을 겪고 있습니다 [10, 11]. 그중에는 다음이 있습니다.

  • 집계 함수 (예 : SUM (), AVG ())는 NULL을 무시합니다 (COUNT () 제외).
  • 행이없는 테이블의 스칼라 표현식은 0 대신 NULL로 잘못 평가됩니다.
  • "NULL = NULL"표현식은 NULL로 평가되지만 실제로는 SQL에서 유효하지 않습니다. 그러나 ORDER BY는 NULL을 동일하게 취급합니다 ( "정규"값보다 먼저 또는 뒤에 오는 것은 DBMS 공급 업체에 남습니다).
  • "V IS NOT NULL"표현식은 2VL에서와 같이 "NOT (x IS NULL)"와 같지 않습니다.

...

상업적으로 구현 된 모든 SQL 언어는이 3VL 방식을 따르므로 이러한 문제를 해결할뿐만 아니라 제품마다 다른 특수 구현 문제가 있습니다 .


4
"그리고 이것은 내 요점이었다 : 값으로서 NULL은"이상한 짐승 "이다." - NULL값이 아니기 때문 입니다.
Pavel Minaev

1
또한 SQL Server는을 제공하지 않습니다 (NULL = NULL) -> FALSE. 설명서를 인용하면 ANSI_NULLS: "ON을 지정하면 NULL 값에 대한 모든 비교로 평가 UNKNOWN OFF를 지정하면 두 값이 모두 NULL 경우, 널 (null) 값이 아닌 유니 코드 값의 비교가 TRUE로 평가합니다.."
파벨 Minaev

@Pavel Minaev : a) 그리고 TRUE가 FALSE보다 얼마나 낫습니까? b) 값이 아닌 경우 왜 변수 값의 일부로 할당됩니까?
MaD70

1
>> 12 월부터 계절별 예를 들어 보겠습니다. 나무 아래에 두 개의 선물이 있습니다. 자, 내가 똑같은 것을 얻었는지 말 해주세요. ..... 네, 당신은 두 가지를 가지고 있고 지금 당장 염려 하는 한, 당신의 현재 지식의 범위 내에서 그것들은 당신과 똑같습니다
Brad Thomas

3
null = null이어야합니다. 널 값은 수 잘 정의되어 표현 미지의 값뿐만 아니라있다 나타내는 없는 값의이. null이 무엇을 나타내는 지 결정하는 것은 개발자의 몫이지만, null 자체는 절대적으로 값이며 null은 null = null입니다. 기본적으로 부울 인 술어에 삼항 논리를 삽입하므로 다른 구현은 재난에 구속됩니다. 나는 이것이 SQL 서버에서 영구적으로 설정되고 있음을 알게되었습니다. 그것으로 OFF OFF OFF.
Triynko

9

어쩌면 그것은 달려 있지만 , 피연산자로 NULL을 사용하는 대부분의 연산 NULL=NULLNULL좋아 한다고 생각 합니다.


9

두 가지가 무엇인지 알지 못한다고해서 둘이 같다는 것은 아닙니다. 당신이 생각할 때 경우에 NULL당신이 "NULL"(문자열) 생각 당신은 아마도 PostgreSQL을의 같은 평등의 다른 테스트 할 IS DISTINCT FROMAND를IS NOT DISTINCT FROM

"비교 함수 및 연산자" 대한 PostgreSQL 문서에서

표현 IS DISTINCT FROM표현

표현 IS NOT DISTINCT FROM표현

널이 아닌 입력의 IS DISTINCT FROM경우 <>연산자 와 동일합니다 . 그러나 두 입력이 모두 null이면 false를 반환하고 하나의 입력 만 null이면 true를 반환합니다. 마찬가지로 널이 아닌 입력의 경우와 IS NOT DISTINCT FROM동일 =하지만 두 입력이 모두 널이면 true를, 하나의 입력 만 널이면 false를 리턴합니다. 따라서 이러한 구성은 "알 수없는"것이 아니라 null이 일반 데이터 값인 것처럼 효과적으로 작동합니다.


5

NULL의 개념은 가장 의문의 여지가 있습니다. Codd는 문맥에서 관계형 모델과 NULL의 개념을 소개하고 (2 종 이상의 NULL을 제안하기 위해 계속되었습니다!) 그러나 관계형 이론은 Codd의 최초 저술 이후 진화했습니다. 다른 사람들은 절대로 붙 잡지 않았습니다 (예 : 세타 운영자). 현대의 관계 이론에서 (진실한 관계 이론에서 나는 스트레스를 받아야한다) NULL은 존재하지 않는다. 세 번째 선언문을 참조하십시오. http://www.thethirdmanifesto.com/

SQL 언어는 이전 버전과의 호환성 문제가 있습니다. NULL은 SQL에서 그 길을 찾았고 우리는 그것에 붙어 있습니다. 아마도 NULLSQL에서 의 구현에 결함이 있습니다 (SQL Server의 구현으로 인해 SQL Server의 구현이 훨씬 복잡해집니다)ANSI_NULLS 옵션 ).

기본 테이블에서 NULL 가능 열을 사용하지 않는 것이 좋습니다.


아마도 유혹을 받아서는 안되지만 NULLSQL에서 작동 하는 방식에 대한 내 자신의 수정 사항을 주장하고 싶었습니다 .

NULL=로 NULL평가됩니다 UNKNOWN.

UNKNOWN 논리 값입니다.

NULL 데이터 값입니다.

이것은 증명하기 쉽다.

SELECT NULL = NULL

SQL Server에서 오류를 올바르게 생성합니다. 결과가 데이터 값이면 NULL여기에 일부 답변이 잘못 제안한 것처럼을 볼 수 있습니다.

논리적 값 UNKNOWN은 SQL DML과 SQL DDL에서 각각 다르게 취급됩니다.

SQL DML에서는 UNKNOWN결과 집합에서 행이 제거됩니다.

예를 들면 다음과 같습니다.

CREATE TABLE MyTable
(
 key_col INTEGER NOT NULL UNIQUE, 
 data_col INTEGER
 CHECK (data_col = 55)
);

INSERT INTO MyTable (key_col, data_col)
   VALUES (1, NULL);

INSERT짝수 불구하고,이 행에 성공 CHECK조건을 해결합니다 NULL = NULL. 이는 SQL-92 ( "ANSI") 표준에 정의되어 있습니다.

11.6 테이블 제약 조건 정의

삼)

테이블 제한 조건이 점검 제한 조건 정의 인 경우, SC를 점검 제한 조건 정의에 즉시 포함 된 검색 조건으로하고 T를 해당 테이블 제한 조건 설명자에 포함 된 테이블 이름으로하십시오. 다음과 같은 경우에만 테이블 제한 조건이 충족되지 않습니다.

기존 (선택하지 않은 곳에서 선택 * (SC))

사실이다.

논리에 따라 다시주의 깊게 읽으십시오.

평범한 영어로, 위의 새로운 행에는 '의심의 혜택'이 주어지고 UNKNOWN통과하는 것이 허용됩니다.

SQL DML에서 WHERE절의 규칙 을 따르는 것이 훨씬 쉽습니다.

탐색 조건은 T의 각 행에 적용됩니다. where 절의 결과는 탐색 조건의 결과가 참인 T의 행에 대한 테이블입니다.

평범한 영어로 평가되는 행 UNKNOWN은 결과 집합에서 제거됩니다.


5

에서 TechNet의 방법 널 (null) 값 작업에 대한 좋은 설명이있다.

널은 알 수 없음을 의미합니다.

따라서 부울 식

값 = 널

false로 평가되지 않고 null로 평가되지만 where 절의 최종 결과 인 경우 아무 것도 반환되지 않습니다. null을 반환하는 것은 임신하기 어렵 기 때문에 그렇게하는 실용적인 방법입니다.

다음을 이해하는 것이 흥미롭고 매우 중요 합니다.

쿼리에서 우리는

where (value=@param Or @param is null) And id=@anotherParam

  • 값 = 1
  • @param이 null입니다
  • id = 123
  • @ anotherParam = 123

그때

"value = @ param"
은 null로 평가되고 "@param은 null"은 true로 평가됩니다.
"id = @ anotherParam"은 true로 평가됩니다.

평가할 표현은

(null 또는 true) 그리고 사실

여기서 "null Or true"는 null로 평가되어 전체 표현식이 null이되고 행이 반환되지 않는다고 생각할 수도 있습니다.

그렇지 않습니다. 왜?

"null Or true"는 매우 논리적 인 true로 평가되기 때문에 하나의 피연산자가 Or 연산자로 true이면 다른 피연산자의 값에 관계없이 연산이 true를 리턴하므로 매우 논리적입니다. 따라서 다른 피연산자를 알 수없는 것은 중요하지 않습니다 (널).

결국 우리는 true = true를 가지므로 행이 반환됩니다.

참고 : "null Or true"가 true로 평가되는 것과 동일한 수정 논리를 사용하면 "null And true"가 null로 평가됩니다.

업데이트 :
좋아, 그냥 완성하기 위해 여기에 나머지를 추가하고 싶습니다. 위와 관련하여 꽤 재미 있습니다.

"null Or false"는 null로 평가되고 "null And false"는 false로 평가됩니다. :)

논리는 물론 이전과 마찬가지로 여전히 자명합니다.


4

때문에 NULL수단 "미지의 값"과 두 개의 미지의 값은 동일 할 수 없다.

따라서 우리의 논리에 따르면 NULLN ° 1이 NULLN ° 2와 같으면 어떻게 든 말해야합니다.

SELECT 1
WHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)

알려진 값 -1N ° 1은 -1N ° 2와 같습니다.


nullParam1 = -1그리고 nullParam2 =NULLairplain 충돌 ....해야합니다ISNULL(NULLIF(@nullParam1, @nullParam2), NULLIF(@nullParam2, nullParam1)) IS NULL
Selvin

4

여기에 대한 답변은 모두 CS 관점에서 나온 것으로 보이므로 개발자 관점에서 하나를 추가하고 싶습니다.

개발자에게는 NULL이 매우 유용합니다. 여기서 대답은 NULL은 알 수 없음을 의미하며 CS 이론에서 사실이라는 것을 기억하십시오. 그러나 실제 개발에서는 적어도 내 경험으로는 약 1 %의 시간이 걸립니다. 다른 99 %는 값을 알 수 없지만 결석 할 수있는 것으로 알려진 경우에 사용됩니다.

예를 들면 다음과 같습니다.

  • Client.LastPurchase새 고객의 경우 그는 아직 구매를하지 않은 것으로 알려져있다.

  • 클래스 계층테이블 맵핑으로 ORM을 사용할 때 일부 값은 특정 클래스에 맵핑되지 않습니다.

  • 트리 구조를 매핑 할 때 루트는 보통Parent = NULL

  • 그리고 더 많은...

나는 어느 시점에서 대부분의 개발자들이 글을 쓰고 WHERE value = NULL아무런 결과도 얻지 못했다고 확신 IS NULL합니다. 이것이 그들이 구문 에 대해 배운 방법 입니다. 이 질문과 연결된 사람들의 투표 수를보십시오.

SQL 데이터베이스는 도구이므로 사용자가 이해하기 가장 쉬운 방식으로 설계해야합니다.


1
모두가“NULL을 알 수 없음”이라고 외친 다음 행동을 정당화합니다. 예, 그것이 전제라면 3VL이 답이 될 것입니다. 그러나 내가 작업하는 거의 모든 DB에서 NULL은 부재 함을 의미합니다. 당신의 목소리가 광야에서 잃어 버려서 죄송합니다 @AlexDev
John Rees

3

NULL은 그 자체가 아닌 다른 것과 동일하지 않습니다. NULL의 동작을 이해하는 나의 개인적인 해결책은 가능한 많이 사용하지 않는 것입니다 :).


1
이 ... 좌 / 우 / 외부 조인의 경우에뿐만 아니라, 모든 것을 동등 수 있습니다
미구엘 벤츄라

5
어리석은 비생산적인 답변입니다. 초등학생들에게 대수학에 대해서도 같은 말을 할 수는 있지만 실제로 해결하려고하는 것을 인정하지 않으면 어리석은 것처럼 나올 것입니다.
Evan Carroll

2
@Evan : 실제로 NULL을 피하는 것이 좋은 해결책입니다. 3 값 논리는 논란의 여지가 없으며, 많은 사람들은 SQL이 NULL이 없으면 SQL이 더 나을 것이라고 생각합니다.
sleske

3
"많은 사람들"은 족제비 단어이며, "논쟁의 여지가 없다"는 3VL이 아닌 더 단순한 "논쟁"을 은폐하는 방법입니다.
Evan Carroll

"NULL은 아무것도 아니라 그 자체도 아니다" 이 논리에 따라 <somevalue>! = NULL은 true를 반환해야합니다. 그러나 SQL의 이상한 우주에서는 거짓입니다.
Tom Lint

3

질문 :
하나의 미지의 것이 다른 미지의 것과 같은가
(NULL = NULL)
이 질문은 아무도 대답 할 수없는 것이 아니므로 ansi_nulls 설정에 따라 기본값은 true 또는 false입니다.

그러나 질문 :
이 알 수없는 변수는 알려지지 않았습니까?
이 질문은 매우 다르며 사실로 대답 할 수 있습니다.

nullVariable = null은 값을 비교합니다
nullVariable is null은 변수의 상태를 비교합니다


3

혼동은 NULL을 사용하여 발생하는 간접 (레벨) 수준에서 발생합니다 .

"크리스마스 트리 아래에있는 것"의 비유로 돌아가서 "알 수 없음"은 박스 A에있는 것에 대한 지식의 상태를 설명합니다.

따라서 박스 A의 내용을 모르는 경우 "알 수 없음"이라고 말하지만 "알 수 없음"이 박스 안에 있음을 의미하지는 않습니다 . 상자에 알려지지 않은 것 이외의 것이있을 수 있습니다.

마찬가지로 Box B의 내용을 모르는 경우 내용에 대한 지식 상태를 "알 수 없음"으로 표시 할 수 있습니다.

여기에 키커가 있습니다. 박스 A에 대한 지식 상태는 박스 B에 대한 지식 상태와 같습니다 . (두 경우 모두 귀하의 지식 상태는 "알 수 없음"또는 "상자에 무엇이 있는지 모르겠습니다"입니다.) 그러나 상자의 내용이 같거나 같지 않을 수 있습니다.

SQL로 돌아가서 이상적으로는 값을 알고있을 때만 값을 비교할 수 있어야합니다. 불행히도 지식 부족을 설명하는 레이블은 셀 자체에 저장 되므로 값으로 사용하려고합니다. 그러나 박스 A의 내용을 알지 못하거나 박스 B의 내용을 알지 못하는 경우 박스 A의 내용이 박스 B의 내용과 같기 때문에 값으로 사용해서는 안됩니다. (논리적으로, "상자 A에 무엇이 있는지 모르고 상자 B에 무엇이 있는지 모른다면, 상자 A에있는 것 = 상자 B에있는 것"은 잘못된 것입니다.

예, 죽은 말.


3

MSDN에는 null과 그들이 생성 한 3 가지 상태 논리에 대한 훌륭한 기사 가 있습니다.

즉, SQL92 스펙은 NULL을 알 수없는 것으로 정의하고 다음 연산자에 사용 된 NULL은 시작되지 않은 사용자에게 예기치 않은 결과를 발생시킵니다.

= operator NULL   true   false 
NULL       NULL   NULL   NULL
true       NULL   true   false
false      NULL   false  true

and op     NULL   true   false 
NULL       NULL   NULL   false
true       NULL   true   false
false      false  false  false

or op      NULL   true   false 
NULL       NULL   true   NULL
true       true   true   true
false      NULL   true   false

그러나 문제는 3VL (3 값 논리)에 관한 것이 아니라 평등의 반사성에 관한 것입니다.
MaD70

더 정확하게 말하면, 마지막으로 답변에서 자세히 설명했듯이 평등이 3VL로 해석 될 때 문제가 발생하여 평등의 반사 속성이 항상 참으로 평가되지는 않습니다.
MaD70 2009

1

SQL에서는 null을 알 수 없으므로 두 알 수없는 것이 같을 것으로 예상 할 수 없습니다.

그러나 ANSI_NULLS를 Off로 설정하면 그 동작을 얻을 수 있습니다 (기본적으로 켜짐) null에 = 연산자를 사용할 수 있습니다

SET ANSI_NULLS off
if null=null
print 1
else 
print 2
set ansi_nulls on
if null=null
print 1
else 
print 2

2
이것은 모든 종류의 아니오 입니다. 세계는의 정의를 가지고 있으며, null그것을 이해하는 방법을 배우거나 테이블을 변경하여 int 유형을 가지며 열을 업데이트합니다.
Evan Carroll

3
SET ANSI_NULLS를 사용하지 않는 것이 좋습니다. ANSI_NULLS에 대해 어려운 방법을 찾았습니다. 그러나 Where SomeId = null ANSI_NULLS에 대한 지식없이 어떻게 그 라인을 이해할 수 있을까요? 내가 보는 방식으로, 내 게시물은 유용했습니다 .. :)
ps.

1

당신은 정부가 시민에 관한 정보를 등록하기 위해 일합니다. 여기에는 국가의 모든 사람에 대한 주민등록번호가 포함됩니다. 약 40 년 전에 아이가 교회 문 앞에 남아 있었는데, 아무도 그들의 부모가 누구인지 모릅니다. 이 사람의 아버지 ID는 NULL입니다. 그러한 두 사람이 존재합니다. 동일한 아버지 ID를 다른 사람 (형제 인 사람)과 공유하는 사람 수를 계산하십시오. 이 둘도 계산합니까?

우리는 그들이 형제인지 아닌지 모르기 때문에 대답은 '아니오'입니다.

당신이없는 가정 NULL이 * = * 옵션을 대신 그럼 당신은 당신의 쿼리 것 등 "알 수없는", 아마도 빈 문자열이나 숫자 0 또는 * 문자를 표현하기 위해 몇 가지 미리 정해진 값을 사용 , 0 = 0 및“”=“”등. 위의 예에 따라 원하는 것은 아니며 위의 예를 자주 잊을 수 있으므로 위의 예는 일상적인 사고 이외의 명확한 프린지 사례입니다. ), NULL = NULL사실이 아닌 언어를 기억해야 합니다.

필요성은 발명의 어머니입니다.


0

다른 훌륭한 답변에 대한 추가 사항 :

AND: The result of true and unknown is unknown, false and unknown is false,
while unknown and unknown is unknown.

OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.

NOT: The result of not unknown is unknown

0

두 개의 NULL에 대해 true를 리턴하는 표현식을 찾고 있다면 다음을 사용할 수 있습니다.

SELECT 1 
WHERE EXISTS (
    SELECT NULL
    INTERSECT
    SELECT NULL
)

한 테이블에서 다른 테이블로 데이터를 복제하려는 경우 유용합니다.


0

예를 들어, case 문 when 절에서 동등성 테스트는

XYZ = NULL 

XYZ IS NULL

공백과 빈 문자열을 NULL과 동일하게 취급하려면 종종 다음과 같은 동등성 테스트를 사용하십시오.

(NULLIF(ltrim( XYZ ),'') IS NULL)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.