SQL cómo hacer que los valores nulos sean últimos al ordenar ascendente


Tengo una tabla SQL con un campo datetime. El campo en cuestión puede ser nulo. Tengo una consulta y quiero que los resultados se ordenen ascendentemente por el campo datetime, sin embargo, quiero filas donde el campo datetime sea nulo al final de la lista, no al principio.

¿Hay una manera sencilla de lograr eso?

Author: David Božjak, 2009-09-30

13 answers

select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
 333
Author: RedFilter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-30 14:59:04

(Un" poco " tarde, pero esto no se ha mencionado en absoluto)

No especificaste tu DBMS.

En SQL estándar (y la mayoría de los DBMS modernos como Oracle, PostgreSQL, DB2, Firebird, Apache Derby, HSQLDB y H2) puede especificar NULLS LAST o NULLS FIRST:

Use NULLS LAST para ordenarlos hasta el final:

select *
from some_table
order by some_column DESC NULLS LAST
 132
Author: a_horse_with_no_name,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-23 09:39:22

También me encontré con esto y lo siguiente parece hacer el truco para mí, en MySQL y PostgreSQL:

ORDER BY date IS NULL, date DESC

Como se encuentra en https://stackoverflow.com/a/7055259/496209

 29
Author: Luksurious,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:08
order by coalesce(date-time-field,large date in future)
 13
Author: Gratzy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-30 15:03:01

Puede usar la función incorporada para verificar si hay null o no null, como se muestra a continuación. Lo pruebo y funciona bien.

select MyDate from MyTable order by ISNULL(MyDate,1) DESC, MyDate ASC;

 12
Author: Majdi M. Aburahelah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-07 09:37:43

Si su motor lo permite ORDER BY x IS NULL, x o ORDER BY x NULLS LAST use eso. Pero si no lo hace estos podrían ayudar:

Si está ordenando por un tipo numérico, puede hacer esto: (Tomando prestado el esquema de otra respuesta.)

SELECT *          
FROM Employees
ORDER BY ISNULL(DepartmentId*0,1), DepartmentId;

resultado mostrando ordenado por DepartmentID con nulos último

Cualquier número no nulo se convierte en 0, y los nulos en 1, lo que ordena los nulos últimos.

También puedes hacer esto para cadenas:

SELECT *
FROM Employees
ORDER BY ISNULL(LEFT(LastName,0),'a'), LastName

resultado mostrando ordenado por LastName con nulls last

Porque 'a' > ''.

Esto incluso funciona con las fechas mediante la coacción a un int nullable y usando el método para ints anterior:

SELECT *
FROM Employees
ORDER BY ISNULL(CONVERT(INT, HireDate)*0, 1), HireDate

(Supongamos que el esquema tiene HireDate.)

Estos métodos evitan el problema de tener que idear o administrar un valor "máximo" de cada tipo o corregir consultas si el tipo de datos (y el máximo) cambia (ambos problemas que sufren otras soluciones ISNULL). Además son mucho más cortos que un caso.

 9
Author: infogulch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:41
SELECT *          
FROM Employees
ORDER BY ISNULL(DepartmentId, 99999);

Ver esta entrada del blog.

 4
Author: user3923117,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-08 14:56:13

Cuando su columna de orden es numérica (como un rango) puede multiplicarla por -1 y luego ordenar descendente. Mantendrá el orden que espera pero pondrá NULL al final.

select *
from table
order by -rank desc
 4
Author: Luizgrs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-26 19:12:54

Gracias a RedFilter por proporcionar una excelente solución al problema de los errores en la ordenación del campo datetime nullable.

Estoy usando la base de datos SQL Server para mi proyecto.

Cambiar el valor null de datetime a '1' resuelve el problema de ordenar la columna datetime datatype. Sin embargo, si tenemos una columna con otro tipo de datos que no sea datetime, entonces no se puede manejar.

Para manejar una clasificación de columna varchar, intenté usar 'ZZZZZZZ' ya que sabía que la columna no tiene valores que comiencen con "Z". Funcionó como se esperaba.

En las mismas líneas, utilicé valores máximos +1 para int y otros tipos de datos para obtener la ordenación como se esperaba. Esto también me dio los resultados que se requerían.

Sin embargo, siempre sería ideal obtener algo más fácil en el motor de base de datos que pudiera hacer algo como:

Order by Col1 Asc Nulls Last, Col2 Asc Nulls First 

Como se menciona en la respuesta proporcionada por a_horse_with_no_name.

 3
Author: Kasim Husaini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-26 12:10:30

En Oracle, puede usar NULLS FIRST o NULLS LAST: especifica que los valores NULOS deben devolverse antes / después de los valores no NULOS:

ORDER BY { column-Name | [ ASC | DESC ] | [ NULLS FIRST | NULLS LAST ] }

Por ejemplo:

ORDER BY date DESC NULLS LAST

Ref: http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html

 2
Author: Joaquinglezsantos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-30 13:27:10
order by -cast([nativeDateModify] as bigint) desc
 1
Author: paparazzo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-08 16:13:52

La solución que usa el "caso" es universal, pero luego no use los índices.

order by case when MyDate is null then 1 else 0 end, MyDate

En mi caso, necesitaba rendimiento.

 SELECT smoneCol1,someCol2  
 FROM someSch.someTab
 WHERE someCol2 = 2101 and ( someCol1 IS NULL ) 
  UNION   
 SELECT smoneCol1,someCol2
 FROM someSch.someTab
 WHERE someCol2 = 2101 and (  someCol1 IS NOT NULL)  
 1
Author: Adam111p,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-23 12:16:54

USE la función NVL

  select * from MyTable order by NVL(MyDate, to_date('1-1-1','DD-MM-YYYY'))

Aquí está la alternativa de NVL en los DBMS más famosos

 0
Author: Charmi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-24 09:58:40