我有一个带日期时间字段的SQL表。有问题的字段可以为空。我有一个查询,我希望结果按datetime字段升序排序,但是我希望datetime字段在列表的末尾而不是开头的行为null。
有没有简单的方法可以做到这一点?
我有一个带日期时间字段的SQL表。有问题的字段可以为空。我有一个查询,我希望结果按datetime字段升序排序,但是我希望datetime字段在列表的末尾而不是开头的行为null。
有没有简单的方法可以做到这一点?
Answers:
select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
order by case when MyDate is null then 1 else 0 end
是很长的说法ORDER BY MyDate IS NULL
order by 0
被解释为列索引,并且列索引基于1。要按第三列对查询进行排序,您可以说order by 3
(对于生产查询来说这是一个糟糕的主意),但是*
在进行实验时非常方便(按原样)。
(一个“位”晚了,但是根本没有提到)
您未指定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
NULLS FIRST
,并NULLS LAST
已在SQL添加了:2003,但没有可利用的在不同DMBS”标准执行。根据数据库引擎的不同,请使用ORDER BY expr some_column DESC NULLS LAST
(Oracle),ORDER BY ISNULL(some_column, 1), some_column ASC
(MSSQL)或ORDER BY ISNULL(some_column), some_column ASC
(具有不同ISNULL()实现的MySQL)。
ASC
/ DESC
,而有些人则不使用null。因此,为了确保这一点的唯一方法,就是使用NULL FIRST/LAST
,如果在DBMS支持它。它记录了您的意图。使用isnull()
或其他功能可以解决缺少的支持NULLS FIRST/LAST
(由Oracle,PostgreSQL,DB2,Firebird,Apache Derby,HSQLDB和H2支持)
expr
在使用NULLS FIRST / LAST时需要关键字。还要感谢第一个/最后一个显示的空值随数据库类型的不同而变化,这不知道!
NULLS LAST
在我的MySQL数据库中无法正常工作。
我也偶然发现了这一点,在MySQL和PostgreSQL上,以下似乎对我有用:
ORDER BY date IS NULL, date DESC
IS NULL
并IS NOT NULL
在我的MySQL数据库没有工作。
order by coalesce(date-time-field,large date in future)
您可以使用内置函数来检查null或不为null,如下所示。我对其进行了测试,并且工作正常。
select MyDate from MyTable order by ISNULL(MyDate,1) DESC, MyDate ASC;
ISNULL(MyDate) DESC, MyDate ASC
它,但是它的排序顺序不正确。
如果您的引擎允许ORDER BY x IS NULL, x
或ORDER BY x NULLS LAST
使用。但是,如果不是这样,这些方法可能会有所帮助:
如果按数字类型排序,则可以执行以下操作:(从另一个答案借用架构。)
SELECT *
FROM Employees
ORDER BY ISNULL(DepartmentId*0,1), DepartmentId;
任何非空数都将变为0,而空值将变为1,这将最后对空值进行排序。
您还可以对字符串执行此操作:
SELECT *
FROM Employees
ORDER BY ISNULL(LEFT(LastName,0),'a'), LastName
因为'a'
> ''
。
这甚至可以通过强制为可为null的int并将上述方法用于int来处理日期:
SELECT *
FROM Employees
ORDER BY ISNULL(CONVERT(INT, HireDate)*0, 1), HireDate
(假设该模式具有HireDate。)
这些方法避免了必须提出或管理每种类型的“最大值”值或在数据类型(和最大值)发生变化时修复查询的问题(这是其他ISNULL解决方案所遇到的问题)。另外,它们比CASE短得多。
当订单列为数字(如等级)时,您可以将其乘以-1,然后降序排列。它将保持您要处理的顺序,但将NULL放在最后。
select *
from table
order by -rank desc
感谢RedFilter为解决可为null的datetime字段排序的问题提供了出色的解决方案。
我正在为我的项目使用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提供的答案中所述。
在Oracle中,可以使用NULLS FIRST
或NULLS LAST
:指定在非NULL值之前/之后返回NULL值:
ORDER BY { column-Name | [ ASC | DESC ] | [ NULLS FIRST | NULLS LAST ] }
例如:
ORDER BY date DESC NULLS LAST
参考:http : //docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj13658.html
如果您使用的是MariaDB,他们会在NULL值文档中提到以下内容。
定购
当您按可能包含NULL值的字段排序时,所有NULL都被视为具有最低值。因此,按DESC顺序排序将看到NULL出现在最后。要强制将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;
就DISTINCT和GROUP BY子句而言,所有NULL值也被视为等效。
上面显示了两种按NULL值排序的方法,您也可以将它们与ASC和DESC关键字结合使用。例如,另一种首先获取NULL值的方法是:
SELECT col1 FROM tab ORDER BY ISNULL(col1) DESC, col1;
-- ^^^^
使用“ 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)
UNION ALL
。
使用NVL功能
select * from MyTable order by NVL(MyDate, to_date('1-1-1','DD-MM-YYYY'))