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 ASC
与 CASE
解决方案一样工作!
@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
)。当然这只适用于数字列。
不错的一个。也适用于date
和time
列! (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的主要内容,如果未能解决你的问题,请参考以下文章