MySQL 按数字排序,最后是 Null

Posted

技术标签:

【中文标题】MySQL 按数字排序,最后是 Null【英文标题】:MySQL Orderby a number, Nulls last 【发布时间】:2011-01-04 07:52:58 【问题描述】:

目前我在我的声明中做了一个非常基本的 OrderBy。

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

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

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

有没有办法实现以下排序:

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

【问题讨论】:

您应该重新考虑 user1052645 的回答。它更简单,不需要知道最大值,并且可能更快(假设评估表达式可能比函数调用更快)。 accepted answer 是错误!!!!!请参阅 here 和 here - ISNULL (field), field ASCCASE 解决方案一样工作! @SteveClay 谁是 user1052645? ORDER BY COALESCE(column_name, 'zz') DESC 【参考方案1】:

mysql 有一个未记录的语法来最后对空值进行排序。在列名前放置一个减号 (-) 并将 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

【讨论】:

这不是无证的,- col_name 是 ORDER BY 子句接受的表达式 (0 - col_name)。当然这只适用于数字列。 不错的一个。也适用于datetime 列! (MySQL 5.5)。我猜(我懒得检查)它适用于所有类似数字的列(时间戳,浮点数......)。 @koral:这是一个简单(且有用)的数学表达式,可以颠倒顺序,除非语言本身发生巨大变化,否则它不会被删除。 正如 cmets 所建议的,它适用于数字、日期和时间列?但是,varchar 呢?它也可以应用于varchar吗?我尝试将其应用于 varchar 字段,但顺序似乎与使用 ASC 或 DESC 不同。 这不会阻止对按列排序的可能索引的使用吗?【参考方案2】:

我发现这在很大程度上是一个很好的解决方案:

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

【讨论】:

不按作品重新定义顺序:SELECT * FROM table ORDER BY ISNULL(field) ASC; (MySQL 5.5) 这是一个更好的解决方案。 接受的解决方案不适用于 postgresql 9.3 中的 TIMESTAMP。这个解决方案确实...... 令人讨厌的是,当您将 isnull(field) 添加到 order by 子句(使用限制时)时,MySQL 不会在字段上使用索引。 @kalu:在 PostgreSQL 中,NULL 值按升序排列last(降序排列在第一个)。你宁愿使用standard SQL clause NULLS LAST | NULLS FIRST 来翻转它,而不是这里的解决方法。【参考方案3】:

NULL LAST

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

【讨论】:

不错的解决方案,你能解释一下吗?【参考方案4】:

有点像

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

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

【讨论】:

这个解决方案很脆弱,可能会导致间歇性错误【参考方案5】:

您可以将 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 函数。 如果您正确地为 IF 语句设置别名,那么行将按照您的预期进行排序。我修正了我的例子。【参考方案6】:

尝试使用此查询:

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

【讨论】:

无需案例。当表达式为 NULL 时,IS NULL 返回 1。请参阅混响的答案。【参考方案7】:

您可以在ORDER BY 语句中coalesce 您的NULL:

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

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

【讨论】:

【参考方案8】:

对于DATE 列,您可以使用:


NULLS 最后:

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

最后一个空格:

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

【讨论】:

【参考方案9】:
SELECT * FROM tablename WHERE visible=1 ORDER BY CASE WHEN `position` = 0 THEN 'a' END , position ASC

【讨论】:

OP 为什么要试试这个好的答案将始终解释所做的事情以及这样做的原因,不仅适用于 OP,而且适用于可能会发现此问题并正在阅读您的答案的 SO 的未来访问者。跨度> 【参考方案10】:

这对我也很有效。

ORDER BY ISNULL(field), field = 0 ASC;

返回 1 2 3 0 0 空值 空

【讨论】:

【参考方案11】:

达到以下效果:

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

使用语法,将-(minus sign)放在字段名之前并使用逆序类型(例如:如果您想按ASC顺序排序,则使用DESC,或者如果您希望DESC顺序,则使用ASC)

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

【讨论】:

【参考方案12】:

这工作正常:

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

position
1 
2
3
0
0

【讨论】:

【参考方案13】:

这很简单。您只需订购两次:

第一步,为 NULL 排序 第二步,订购您的田地。
SELECT * FROM table_name 
ORDER BY ISNULL(field_name), field_name;

它适用于任何类型,包括 JSON。

【讨论】:

【参考方案14】:

你为什么不按 NULLS LAST 排序?

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

【讨论】:

NULLS LAST - 引入了哪个版本的 MySQL? @Panique,你的意思是(MS)SQL Server? 这个答案不适用于 MySQL 此解决方案适用于 java db 但不适用于 mysql

以上是关于MySQL 按数字排序,最后是 Null的主要内容,如果未能解决你的问题,请参考以下文章

sql 如何优先显示不为空的字段 并进行排序

MySql排序查询将null放在最后的解决办法(默认会在最前,当成最小值处理)

MySQL按多列排序,忽略最后按指令排序

MySql:按父子顺序排序

order by 升序排序是null字段如何排在最后?

按文件名排序 linux