지금은 2017 년이지만, NULL
s가 우선해야하는지 에 대한 합의는 아직 없습니다 . 그것에 대해 명시하지 않으면 결과는 DBMS에 따라 달라질 것입니다.
표준은 NULL이 아닌 값과 비교하여 NULL을 정렬하는 방법을 지정하지 않습니다. 단 두 개의 NULL이 동일한 순서로 간주되고 NULL이 모든 NULL이 아닌 값의 위 또는 아래로 정렬되어야한다는 점을 제외하고는 예외입니다.
소스, 대부분의 DBMS 비교
문제를 설명하기 위해 Rails 개발과 관련하여 가장 많이 사용되는 몇 가지 사례 목록을 작성했습니다.
PostgreSQL
NULL
의 값이 가장 높습니다.
기본적으로 null 값은 null이 아닌 값보다 큰 것처럼 정렬됩니다.
출처 : PostgreSQL 문서
MySQL
NULL
의 값이 가장 낮습니다.
ORDER BY를 수행 할 때 ORDER BY ... ASC를 수행하면 NULL 값이 먼저 표시되고 ORDER BY ... DESC를 수행하면 마지막으로 표시됩니다.
출처 : MySQL 문서
SQLite
NULL
의 값이 가장 낮습니다.
NULL 값이있는 행은 오름차순으로 일반 값이있는 행보다 높으며 내림차순으로 반전됩니다.
출처
해결책
불행히도 Rails 자체는 아직 이에 대한 솔루션을 제공하지 않습니다.
PostgreSQL 관련
PostgreSQL의 경우 매우 직관적으로 사용할 수 있습니다.
Photo.order('collection_id DESC NULLS LAST') # NULLs come last
MySQL 특정
MySQL의 경우 마이너스 기호를 미리 입력 할 수 있지만이 기능은 문서화되지 않은 것 같습니다. 숫자 값뿐만 아니라 날짜에서도 작동하는 것처럼 보입니다.
Photo.order('-collection_id DESC') # NULLs come last
PostgreSQL 및 MySQL 관련
두 가지를 모두 다루려면 다음과 같이 작동합니다.
Photo.order('collection_id IS NULL, collection_id DESC') # NULLs come last
그러나 이것은 SQLite에서 작동하지 않습니다 .
범용 솔루션
모든 DBMS에 대한 교차 지원을 제공하려면 CASE
이미 @PhilIT에서 제안한를 사용하여 쿼리를 작성해야합니다 .
Photo.order('CASE WHEN collection_id IS NULL THEN 1 ELSE 0 END, collection_id')
이는 각 레코드를 먼저 CASE
결과 (기본적으로 오름차순, 즉 NULL
값이 마지막 값이 됨을 의미 함) 별로 먼저 정렬 하고 두 번째는 calculation_id
.