답변:
왜 조인을 위해 널이 널과 같을 수 없습니까?
오라클에게 다음과 같이 지시하십시오.
select *
from one t1
join two t2 on coalesce(t1.id, -1) = coalesce(t2.id, -1);
(표준 SQL t1.id is not distinct from t2.id
에서는 널 안전 항등 연산자를 얻는 데 사용할 수 있지만 Oracle은이를 지원하지 않습니다.)
그러나 이것은 대체 값 (위의 예에서 -1)이 실제로 표에 나타나지 않는 경우에만 작동합니다. 숫자와 같은 "마법"값을 찾는 것은 수도 가능하지만, 문자 값에 매우 어려울 것이다 (특히 때문에 오라클 취급 빈 문자열 null
뿐만 아니라)
또한 : id
열의 인덱스 가 사용 되지 않습니다 ( 하지만 표현식을 사용하여 함수 기반 인덱스를 정의 할 수 있음coalesce()
).
마법 값없이 모든 유형에 적용되는 다른 옵션 :
on t1.id = t2.id or (t1.id is null and t2.id is null)
그러나 실제 문제는 이것이 의미가 있습니까?
다음 샘플 데이터를 고려하십시오.
표 하나
id
----
1
2
(null)
(null)
표 2
id
----
1
2
(null)
(null)
(null)
조인에서 어떤 null 값 조합을 선택해야합니까? 위의 예제는 모든 null 값에 대한 크로스 조인과 같은 결과를 낳습니다.
T1_ID | T2_ID
-------+-------
1 | 1
2 | 2
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
(null) | (null)
또는 INTERSECT
등식 연산자로 두 개의 null을 서로 일치시킬 수 있습니다 .
SELECT
*
FROM
t1
INNER JOIN t2
ON EXISTS (SELECT t1.ID FROM DUAL INTERSECT SELECT t2.ID FROM DUAL)
;
그림은 이 DBFiddle 데모 를 참조하십시오 .
물론 이것은 실제로는 더 길지 않지만 상당히 입으로 보입니다. BriteSponge의 제안 . 그러나, 말장난을 용서한다면, 앞서 언급 한 표준의 간결함에 대해서는 표준 방식 ( IS NOT DISTINCT FROM
오퍼레이터에서는 아직 지원되지 않음)으로 명확하게 일치하지 않습니다.
완전성을 위해 함수가 SYS_OP_MAP_NONNULL
을 기하기 위해 12c 문서에 문서화되어 있으므로 null 값을 비교하는 데 를 안전하게 사용할 수 . 이것은 오라클이 무작위로 코드를 제거하지 않고 코드를 손상시키지 않는다는 것을 의미합니다.
SELECT *
FROM one t1
JOIN two t2
ON SYS_OP_MAP_NONNULL(t1.id) = SYS_OP_MAP_NONNULL(t2.id)
장점은 '매직'숫자 문제를 겪지 않는다는 것입니다.
Oracle 문서의 참조는 기본 구체화 된 뷰 – 구체화 된 뷰에 대한 인덱스 선택에 있습니다.
왜 조인에 null 값을 사용할 수 없습니까? Oracle에서는 다음 두 가지 모두 사실로 평가되지 않습니다.
NULL = NULL
NULL <> NULL
우리가 이유 IS NULL
/ IS NOT NULL
널 (null) 값을 확인 할 수 있습니다.
이를 테스트하려면 다음을 수행하십시오.
SELECT * FROM table_name WHERE NULL = NULL
조인은 부울 조건을 평가하고 있으며 다르게 작동하도록 프로그래밍하지 않았습니다. 결합 조건에보다 큰 부호를 넣고 다른 조건을 추가 할 수 있습니다. 그것은 단지 그것을 불리언 표현식으로 평가합니다.
일관성을 위해 조인에서 null은 null과 같을 수 없습니다. 비교 연산자의 일반적인 동작을 무시합니다.
NULL = anything
결과 NULL
SQL 표준 그렇게 말한다 때문이다. 표현식이 true 인 경우에만 행이 결합 조건을 충족시킵니다.
대부분의 관계형 데이터베이스에서 널값은 알 수없는 것으로 간주됩니다. 모든 HEX 0과 혼동해서는 안됩니다. 무언가에 null (알 수 없음)이 포함되어 있으면 비교할 수 없습니다.
Unknown = Known False
Unknown = Unknown False
Unknown >= Known False
Known >= Unknown False
즉, 부울 식에서 피연산자로 null이 있으면 else 부분은 항상 참입니다.
개발자에 의한 null에 대한 일반적인 증오와 달리 null은 그 자리에 있습니다. 알 수없는 경우 null을 사용하십시오.
UNKNOWN
FALSE
where (a = b or (a is null and b is null))
기간. 그것이 저의 생각입니다. 나는sys_op_map_nonnull
커튼 뒤에있는 사람을 무시하고 사용 하는 것을 고려하지 않을 것 입니다. "