我有一个带有日期时间字段的SQL表。有问题的字段可以为null。我有一个查询,我希望结果按日期时间字段按升序排序,但是我想要在列表末尾的datetime字段为空的行,而不是在开头。
有没有一种简单的方法可以实现这一目标?
答案 0 :(得分:358)
select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
答案 1 :(得分:142)
(“有点”迟到了,但根本没有提到过)
您没有指定DBMS。
在标准SQL(以及大多数现代DBMS,如Oracle,PostgreSQL,DB2,Firebird,Apache Derby,HSQLDB和H2)中,您可以指定NULLS LAST
或NULLS FIRST
:
使用NULLS LAST
将它们排序到最后:
select *
from some_table
order by some_column DESC NULLS LAST
答案 2 :(得分:32)
我也偶然发现了这一点,以下似乎对我有所帮助,在MySQL和PostgreSQL上:
ORDER BY date IS NULL, date DESC
处找到
答案 3 :(得分:14)
order by coalesce(date-time-field,large date in future)
答案 4 :(得分:13)
您可以使用内置函数检查null或not null,如下所示。我测试它并且工作正常。
select MyDate from MyTable order by ISNULL(MyDate,1) DESC, MyDate ASC;
答案 5 :(得分:9)
如果您的引擎允许ORDER BY x IS NULL, x
或ORDER BY x NULLS LAST
使用该引擎。但如果不是这些可能会有所帮助:
如果您按数字类型排序,则可以执行以下操作:(从another answer借用架构。)
SELECT *
FROM Employees
ORDER BY ISNULL(DepartmentId*0,1), DepartmentId;
任何非空数字都变为0,空值变为1,最后对空值进行排序。
您也可以为字符串执行此操作:
SELECT *
FROM Employees
ORDER BY ISNULL(LEFT(LastName,0),'a'), LastName
因为'a'
> ''
。
这甚至可以通过强制转换为可空int并使用上面的int方法来处理日期:
SELECT *
FROM Employees
ORDER BY ISNULL(CONVERT(INT, HireDate)*0, 1), HireDate
(让我假装架构有HireDate。)
这些方法避免了如果数据类型(和最大值)发生变化(两个ISNULL解决方案都遇到的问题),必须提出或管理每种类型的“最大”值或修复查询的问题。而且它们比CASE短得多。
答案 6 :(得分:6)
当您的订单栏是数字(如排名)时,您可以将其乘以-1然后按顺序递减。它会保留您要求的顺序,但最后会保留NULL。
select *
from table
order by -rank desc
答案 7 :(得分:4)
答案 8 :(得分:3)
感谢RedFilter为排序可为空的日期时间字段提供了出色的解决方案。
我正在为我的项目使用SQL Server数据库。
将datetime null值更改为“1”确实解决了datetime数据类型列的排序问题。但是,如果我们的列不是datetime数据类型,那么它就无法处理。
为了处理varchar列排序,我尝试使用'ZZZZZZZ',因为我知道列没有以'Z'开头的值。它按预期工作。
在同一行中,我使用int和其他数据类型的最大值+1来获得预期的排序。这也给了我所需的结果。
然而,在数据库引擎本身中获得更容易的东西总是理想的,这可以做类似的事情:
Order by Col1 Asc Nulls Last, Col2 Asc Nulls First
如a_horse_with_no_name提供的答案所述。
答案 9 :(得分:3)
在Oracle中,您可以使用bin/console h:d:f:l
或NULLS FIRST
:指定应在非NULL值之前/之后返回NULL值:
NULLS LAST
例如:
ORDER BY { column-Name | [ ASC | DESC ] | [ NULLS FIRST | NULLS LAST ] }
参考:http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html
答案 10 :(得分:1)
order by -cast([nativeDateModify] as bigint) desc
答案 11 :(得分:1)
使用“case”的解决方案是通用的,但是不要使用索引。
order by case when MyDate is null then 1 else 0 end, MyDate
就我而言,我需要表现。
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)
答案 12 :(得分:0)
USE NVL功能
select * from MyTable order by NVL(MyDate, to_date('1-1-1','DD-MM-YYYY'))
答案 13 :(得分:0)
如果您使用的是MariaDB,他们会在NULL Values documentation中提及以下内容。
Ordering
当您按可能包含NULL值的字段排序时,所有NULL均为 被认为具有最低的价值。因此,按DESC顺序订购将看到 空值最后出现。要强制将NULL视为最高值,可以 当主字段为NULL时,添加另一个具有较高值的列。 示例:
SELECT col1 FROM tab ORDER BY ISNULL(col1), col1;
降序,首先为NULL:
SELECT col1 FROM tab ORDER BY IF(col1 IS NULL, 0, 1), col1 DESC;
出于以下目的,所有NULL值也被视为等效 DISTINCT和GROUP BY子句。
上面显示了两种按NULL值排序的方法,您可以将它们与 以及ASC和DESC关键字。例如,另一种获取NULL值的方法 首先是:
SELECT col1 FROM tab ORDER BY ISNULL(col1) DESC, col1;
-- ^^^^