MySQL Ordenar por un número, Nulos últimos


280

Actualmente estoy haciendo un OrderBy muy básico en mi declaración.

SELECT * FROM tablename WHERE visible=1 ORDER BY position ASC, id DESC

El problema con esto es que las entradas NULL para 'posición' se tratan como 0. Por lo tanto, todas las entradas con posición como NULL aparecen antes que aquellas con 1,2,3,4. p.ej:

NULL, NULL, NULL, 1, 2, 3, 4

¿Hay alguna manera de lograr el siguiente orden:

1, 2, 3, 4, NULL, NULL, NULL.

8
Debería reconsiderar la respuesta del usuario 1052645. Es más simple, no requiere conocimiento de los valores máximos y podría ser más rápido (suponiendo que evaluar una expresión puede ser más rápido que una llamada a función).
Steve Clay

Respuestas:


568

MySQL tiene una sintaxis no documentada para ordenar los nulos en último lugar. Coloque un signo menos (-) antes del nombre de la columna y cambie el ASC a DESC:

SELECT * FROM tablename WHERE visible=1 ORDER BY -position DESC, id DESC

Es esencialmente lo position DESCcontrario de colocar los valores NULOS al final, pero por lo demás es lo mismo que position ASC.

Una buena referencia está aquí http://troels.arvin.dk/db/rdbms#select-order_by


79
No está indocumentado, - col_namees una expresión ( 0 - col_name), que acepta la cláusula ORDER BY. Por supuesto, esto solo funciona para columnas numéricas.
Steve Clay

77
Buena esa. Funciona para datey timecolumnas también! (MySQL 5.5). Supongo (que soy lento para verificar) funciona para todas las columnas de tipo numérico (marca de tiempo, flotante ...).
Martin

66
@koral: es una expresión matemática simple (y útil) que invierte el orden, no se eliminará a menos que el lenguaje en sí cambie drásticamente.
Bell

11
Como sugieren los comentarios, ¿funciona para columnas numéricas, de fecha y hora? Pero, ¿qué hay de varchar? ¿Se puede aplicar también para varchar? Intenté aplicarlo a los campos varchar, pero el orden parece ser diferente de usar ASC o DESC.
Sumit Desai

9
¿Esto no impedirá el uso de un posible índice en el pedido por columna?
Tarsis

306

Encontré que esta es una buena solución en su mayor parte:

SELECT * FROM table ORDER BY ISNULL(field), field ASC;

66
Sin redefinir el orden por obras: SELECT * FROM table ORDER BY ISNULL(field) ASC;(MySQL 5.5)
Marçal Juan

55
Esta es una mejor solución.
Rok Kralj

44
La solución aceptada no funciona con TIMESTAMP en postgresql 9.3. Esta solución hace ...
Kalu

2
Molesto, MySQL no usará un índice en el campo cuando agrega isnull (campo) al orden por cláusula (cuando usa límite).
Barry Kelly

3
@kalu: en PostgreSQL , los valores NULL se ordenan en último lugar en orden ascendente (y primero en orden descendente). Y prefiere usar la cláusula SQL estándarNULLS LAST | NULLS FIRSTpara voltearlo en lugar de las soluciones alternativas aquí.
Erwin Brandstetter

23

Algo como

SELECT * FROM tablename where visible=1 ORDER BY COALESCE(position, 999999999) ASC, id DESC

Reemplace 999999999 con el valor máximo para el campo


3
Esta solución es frágil y puede provocar errores intermitentes
Dmitry Bogdanovich

20

NULO ÚLTIMO

SELECT * FROM table_name ORDER BY id IS NULL, id ASC

4

Puede intercambiar instancias de NULL con un valor diferente para ordenarlas primero (como 0 o -1) o la última (un número grande o una letra) ...

SELECT field1, IF(field2 IS NULL, 9999, field2) as ordered_field2
  FROM tablename
 WHERE visible = 1
 ORDER BY ordered_field2 ASC, id DESC

Esto no resolverá el problema ya que el índice al que se hace referencia en ORDER BY no se verá afectado al reemplazar los valores en la instrucción SELECT y, por lo tanto, no corregirá el orden. Además, consulte la función COALESCE, que es funcionalmente equivalente a su uso de la función IF.
define el

Si alias la instrucción IF correctamente, las filas se ordenan como es de esperar. Arreglé mi ejemplo.
Langdon el

4

Intenta usar esta consulta:

SELECT * FROM tablename
WHERE visible=1 
ORDER BY 
CASE WHEN position IS NULL THEN 1 ELSE 0 END ASC,id DESC

No es necesario para el caso. IS NULL devuelve 1 cuando la expresión es NULL. Ver la respuesta de reverbnation.
contactmatt

3

Puede fusionar sus NULL en la ORDER BYdeclaración:

select * from tablename
where <conditions>
order by
    coalesce(position, 0) ASC, 
    id DESC

Si desea que los NULL se ordenen en la parte inferior, intente coalesce(position, 100000). (Haga el segundo número más grande que todos los demás positionen la base de datos).


3
SELECT * FROM tablename WHERE visible=1 ORDER BY CASE WHEN `position` = 0 THEN 'a' END , position ASC

66
¿Por qué el OP debería intentar esto ? Las buenas respuestas siempre tendrán una explicación de lo que se hizo y por qué se hizo de esa manera, no solo para el OP sino para los futuros visitantes a SO que pueden encontrar esta pregunta y leer su respuesta.
RiggsFolly

2

Para una DATEcolumna puede usar:


NULOS últimos:

ORDER BY IFNULL(`myDate`, '9999-12-31') ASC

Los últimos espacios en blanco:

ORDER BY IF(`myDate` = '', '9999-12-31', `myDate`) ASC

1

Para lograr el siguiente resultado:

1, 2, 3, 4, NULL, NULL, NULL.

USE la sintaxis, coloque -(minus sign)antes del nombre del campo y use el tipo de orden inverso (como: si desea ordenar por orden ASC, use DESC o si desea orden DESC, use ASC)

SELECT * FROM tablename WHERE visible=1 ORDER BY -position DESC


1

Esto está funcionando bien:

SELECT * FROM tablename ORDER BY position = 0, position ASC;

position
1 
2
3
0
0

-8

¿Por qué no ordena por NULLS ULTIMO?

SELECT * 
FROM tablename
WHERE visible = 1 
ORDER BY position ASC NULLS LAST, id DESC 

NULLS LAST- ¿Qué versión de MySQL se introdujo?
crmpicco

2
@Panique, ¿te refieres a (MS) SQL Server?
d -_- b

1
esta respuesta no se aplica a MySQL
PeppyHeppy
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.