지금은 2017 년이지만, NULLs가 우선해야하는지 에 대한 합의는 아직 없습니다 . 그것에 대해 명시하지 않으면 결과는 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.