왜 NULL이 먼저 정렬됩니까?


20

열에 NULL 값이 있고 오름차순으로 정렬 할 때 NULL이 먼저 정렬되는 이유는 무엇입니까?

select 1 as test
union all
select 2
union all
select NULL
union all
select 3
union all
select 4
order by test

결과

NULL
1
2
3
4

NULL은 "불확정"또는 가능한 "알 수 없음"을 의미한다고 계속 생각합니다. 그것이 사실이라면, 값이 다른 모든 값보다 클 수 있기 때문에 마지막으로 정렬되지 않습니까? (또는 어딘가에 정렬 옵션입니까?)

SQL Server 2008R2를 사용하고 있지만 모든 SQL Server 및 모든 RDBMS에서 이것이 사실이라고 생각합니다.


1
오라클은이를 마지막으로 나열합니다. 그것은 SQL Server처럼 행동해야한다고 믿어 나를 한 번 망치게했습니다.
Andrei Rînea

2
"만약 그것이 사실이라면, 그 값은 다른 모든 값보다 클 수 있기 때문에 마지막으로 정렬되지 않을 것입니다." 값이 다른 모든 값보다 작을 수 있습니다. 나에게는 null과 같은 잘못된 값이 하단에 있어야한다는 것은 직관적입니다. 그리고 실제로, 실제로, 당신은 종종 desc가장 큰 것 또는 가장 최근의 것을 보여주기 위해 순서 를 사용하기를 원합니다 .
mahemoff

데이터베이스는 사용자가 지시 한 작업을 수행합니다. 데이터에 널이 포함되어 있고 특정 방식으로 데이터를 정렬해야하는 몇 가지 비즈니스 이유가있는 경우 쿼리 또는 데이터를 처리 / 표시하는 코드 / 뷰에서이를 지정해야합니다. 기본 데이터베이스 동작까지 정렬하지 마십시오.
아무것도 불필요

답변:


19

BOL : NULL 값은 값을 알 수 없음을 나타냅니다. NULL 값은 비어 있거나 0 값과 다릅니다. 두 개의 null 값이 동일하지 않습니다. 두 NULL 값 사이 또는 NULL과 다른 값 사이의 비교는 각 NULL의 값을 알 수 없으므로 알 수 없음을 리턴합니다.

NULL은 알 수 없음을 의미합니다. 다른 해석은 유효하지 않습니다.

그것이 사실이라면, 값이 다른 모든 값보다 클 수 있기 때문에 마지막으로 정렬되지 않습니까?

있을 수 없습니다 . 잠재적 가치 가 없습니다 . 알 수 없음 알 수 없음

이것이 마지막이 아니라 첫 번째로 나타나는 이유에 대해서는 게시 된 SQL 표준에 따라 제공되지 않으며 불행히도 RDBMS 공급 업체의 재량에 달려 있습니다.

Wikipedia : SQL 표준은 널에 대한 기본 정렬 순서를 명시 적으로 정의하지 않습니다. 대신, 순응 시스템에서 ORDER BY 목록의 NULLS FIRST 또는 NULLS LAST 절을 각각 사용하여 모든 데이터 값 전후에 널을 정렬 할 수 있습니다. 그러나 모든 DBMS 공급 업체가이 기능을 구현하지는 않습니다. 이 기능을 구현하지 않은 공급 업체는 DBMS에서 널 정렬에 대해 다른 처리를 지정할 수 있습니다.


그래서 그것은 판단 요청입니다. 그것은 많은 의미가 있습니다. 감사!
Richard

6

당신은 올바른 NULL'적용되지 않음' 'Indeterminant'또는 'Uknownn'또는 '아직 알려진'또는를 의미 할 수있다. 그러나 널을 맨 처음 또는 마지막으로 넣을 이유가 없습니다. 실제 값을 모른다면 tehy는 작거나 클 수 있습니다.

정렬하는 동안 Nulls의 원하는 동작을 결정하는 표준은 다음과 같습니다.

ORDER BY 
    test NULLS LAST                      --- or NULLS FIRST for the opposite

불행히도 SQL-Server는이 구문을 아직 채택하지 않았습니다. 내가 틀리지 않으면 PostgreSQL과 Oracle에 있습니다.

하나의 솔루션 :

ORDER BY 
     CASE WHEN test IS NOT NULL 
            THEN 0 
          ELSE 1 
     END 
   , test

데이터 유형에 따라 조정이 필요한 다른 솔루션이지만 인덱스를 사용할 수 없으므로 제대로 수행되지 않습니다 (test).

ORDER BY 
    COALESCE(test, 2147483647)               --- if it's a 4-byte signed integer

이런 식으로 ORDER BY COALESCE (test, 2147483647) SQL Server는 인덱스를 사용할 수 없습니다.
Ardalan Shahgholi

3

내가 모르는 이유 가 그런 식으로 일을,하지만 그들은 하나의 시작 또는 끝 부분에 갈 필요가 있도록 정의 NULLS에 의해, 비 NULLS 비교할 수없는 (마크의 대답은 훨씬 더 자세하게을 포함).

원하는 동작을 얻으려면-마지막으로 null을 넣는 정렬 옵션이 없으므로 계산 열을 사용하여 마지막으로 강제로 정렬해야합니다. 그러나 SQL Server에서는 CASE WHEN ...데이터에 집합 연산자 ( UNION ALL) 가 포함 된 경우 계산 열 ( )로 정렬 할 수 없습니다 . 그래서:

CREATE TABLE #sorttest(test int)
INSERT INTO #sorttest values(1)
INSERT INTO #sorttest values(5)
INSERT INTO #sorttest values(4)
INSERT INTO #sorttest values(NULL)
INSERT INTO #sorttest values(3)
INSERT INTO #sorttest values(2)
SELECT test
FROM #sorttest
ORDER BY CASE WHEN test IS NULL THEN 1 ELSE 0 END, test

DROP TABLE #sorttest

마지막으로 null을 정렬하는 데 효과적입니다. 데이터 세트를 생성 하기 위해 UNION(또는 EXCEPT또는 INTERSECTS) 를 사용해야하는 경우 위와 같이 데이터를 임시 테이블에 덤프하십시오.


... 또는 UNIONed 출력을 파생 테이블로 사용하십시오.
Andriy M

0

숫자를 다루는 경우에도 사용할 수 있습니다

ORDER BY -test DESC

NULL가장 낮은 값이므로 DESC끝 부분에 넣습니다. 한편 null이 아닌 값은 부호가 반전되어 DESC실제로 ASC실제 값에 있습니다. 이것은보다 빠르며 CASE쿼리 최적화 프로그램이 test열에서 인덱스를 사용할 수도 있다고 가정합니다 .


3
아니요, 정렬에 색인을 사용할 수 없습니다. 계산 된 표현식에 대한 색인이없는 한 (- test).
ypercubeᵀᴹ

1
영리하지만 숫자 데이터로만 제한되지만 OP의 예에 적합합니다. 이것이 실제로 CASE를 사용하는 것보다 빠를 지 확실하지 않지만 인덱스를 사용하지 않을 것이라고 확신합니다 (@ ypercubeᵀᴹ의 말이 아닌 한 CASE 표현식은 정확히 동일한 방식으로 색인화 될 수 있음).
Andriy M
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.