MySQL Orderby一个数字,Null为最后


279

目前,我在声明中正在执行一个非常基本的OrderBy。

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

问题是“位置”的NULL条目被视为0。因此,所有位置为NULL的条目都出现在具有1,2,3,4的条目之前。例如:

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

有没有一种方法可以实现以下排序:

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

8
您应该重新考虑user1052645的答案。它更简单,不需要最大值的知识,并且可能更快(假设评估表达式可能比函数调用更快)。
史蒂夫·克莱

Answers:


566

MySQL具有未记录的语法,可以最后对null进行排序。在列名之前放置减号(-),然后将ASC切换为DESC:

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

从本质上讲,这与position DESC将NULL值最后放置相反,但与相同position ASC

一个很好的参考在这里http://troels.arvin.dk/db/rdbms#select-order_by


79
它不是未记录的,- col_name0 - col_nameORDER BY子句接受的表达式()。当然,这仅适用于数字列。
史蒂夫·克莱

7
好一个。适用于datetime列!(MySQL 5.5)。我猜(我懒于检查)它适用于所有类似数字的列(时间戳,浮点数...)。
马丁

6
@koral:这是一个简单(且有用)的数学表达式,可以颠倒顺序,除非语言本身发生巨大变化,否则它不会被删除。
贝尔

11
正如评论所建议的,它适用于数字,日期和时间列?但是,varchar呢?它也可以应用于varchar吗?我尝试将其应用于varchar字段,但是顺序似乎与使用ASC或DESC的顺序不同。
Sumit Desai 2014年

9
这是否会阻止使用按列排序的可能索引?
Tarsis

305

我发现这在大多数情况下是一个很好的解决方案:

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

6
如果没有通过作品重新定义命令:SELECT * FROM table ORDER BY ISNULL(field) ASC;(MySQL的5.5)
马萨尔胡安

5
这是一个更好的解决方案。
Rok Kralj 2013年

4
可接受的解决方案不适用于PostgreSQL 9.3中的TIMESTAMP。此解决方案确实...
kalu 2014年

2
烦人的是,当您向order by子句中添加isnull(field)时(使用限制时),MySQL将不会在字段上使用索引。
巴里·凯利

3
@kalu:在PostgreSQL中,NULL值最后以升序排序(并且首先是降序排序)。而且您宁愿使用标准的SQL子句NULLS LAST| NULLS FIRST翻转它而不是这里的解决方法。
Erwin Brandstetter,2016年

23

就像是

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

将999999999替换为该字段的最大值


3
该解决方案是脆弱的,可能会导致间歇性的错误
梅德诺维奇

20

空最后

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

4

您可以换出具有不同值的NULL实例,以便对它们进行优先排序(例如0或-1)或最后排序(较大的数字或字母)...

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

这不会解决问题,因为在ORDER BY中引用的索引不会受到替换SELECT语句中的值的影响,因此不会更正顺序。另外,请检查COALESCE函数,该函数在功能上等同于您使用IF函数。
定义2010年

如果正确命名IF语句,则行将按您期望的顺序排列。我修正了我的例子。
兰登


3

您可以在语句中合并 NULL ORDER BY

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

如果要让NULL在底部排序,请尝试coalesce(position, 100000)。(使第二个数字大于数据库中所有其他数字position。)


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

6
OP为什么要尝试这个好的答案总是可以解释这样做的原因以及这样做的原因,不仅对于OP,对于将来的SO访客而言,他们可能会发现此问题并正在阅读您的答案。
RiggsFolly


1

要达到以下结果:

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

使用语法,将其放在-(minus sign)字段名称之前,并使用相反的order_type(例如:如果要按ASC顺序进行订购,则使用DESC;如果要DESC顺序,则使用ASC)

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


1

这工作正常:

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

position
1 
2
3
0
0

-8

您为什么不按NULLS LAST订购?

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

NULLS LAST-引入了哪个版本的MySQL?
crmpicco 2012年

2
@Panique,您的意思是(MS)SQL Server?
d -_- b

1
此答案不适用于MySQL
PeppyHeppy 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.