A pesar de que estamos en 2017, todavía no existe un consenso sobre si las NULL
s deben tener prioridad. Sin que sea explícito al respecto, sus resultados variarán según el DBMS.
El estándar no especifica cómo deben ordenarse los NULL en comparación con los valores no NULL, excepto que dos NULL cualesquiera deben considerarse igualmente ordenados, y que los NULL deben ordenarse por encima o por debajo de todos los valores no NULL.
fuente, comparación de la mayoría de DBMS
Para ilustrar el problema, compilé una lista de algunos de los casos más populares cuando se trata del desarrollo de Rails:
PostgreSQL
NULL
s tienen el valor más alto.
De forma predeterminada, los valores nulos se ordenan como si fueran más grandes que cualquier valor no nulo.
fuente: documentación de PostgreSQL
MySQL
NULL
s tienen el valor más bajo.
Al hacer un ORDER BY, los valores NULL se presentan primero si hace ORDER BY ... ASC y por último si hace ORDER BY ... DESC.
fuente: documentación de MySQL
SQLite
NULL
s tienen el valor más bajo.
Una fila con un valor NULL es más alta que las filas con valores regulares en orden ascendente y se invierte en orden descendente.
fuente
Solución
Desafortunadamente, Rails todavía no ofrece una solución.
Específico de PostgreSQL
Para PostgreSQL, podría usar de manera bastante intuitiva:
Photo.order('collection_id DESC NULLS LAST') # NULLs come last
Específico de MySQL
Para MySQL, puede poner el signo menos al principio, pero esta función parece no estar documentada. Parece funcionar no solo con valores numéricos, sino también con fechas.
Photo.order('-collection_id DESC') # NULLs come last
PostgreSQL y MySQL específicos
Para cubrir ambos, esto parece funcionar:
Photo.order('collection_id IS NULL, collection_id DESC') # NULLs come last
Aún así, este no funciona en SQLite.
Solución universal
Para proporcionar soporte cruzado para todos los DBMS, tendría que escribir una consulta usando CASE
, ya sugerido por @PhilIT:
Photo.order('CASE WHEN collection_id IS NULL THEN 1 ELSE 0 END, collection_id')
lo que se traduce en ordenar primero cada uno de los registros primero por CASE
resultados (en orden ascendente predeterminado, lo que significa que los NULL
valores serán los últimos), segundo por calculation_id
.