按 ASC 列排序,但首先是 NULL 值?

Posted

技术标签:

【中文标题】按 ASC 列排序,但首先是 NULL 值?【英文标题】:Sort by column ASC, but NULL values first? 【发布时间】:2012-03-19 14:40:04 【问题描述】:

我需要按日期/时间字段升序对 PostgreSQL 表进行排序,例如last_updated.

但该字段允许为空或 null,我希望 last_updated 中为 null 的记录出现在 之前非 null last_updated。 这可能吗?

order by last_updated asc  -- and null last_updated records first ??

【问题讨论】:

【参考方案1】:

Postgres 有 NULLS FIRST | LAST 修饰符用于 ORDER BY 表达式:

... ORDER BY last_updated NULLS FIRST

典型用例是降序排序 (DESC),这会产生默认升序的完全反转 ( ASC)首先使用空值 - 这通常是不可取的。最后对NULL 值进行排序:

... ORDER BY last_updated DESC NULLS LAST

要支持带有索引的查询,请使其匹配:

CREATE INDEX foo_idx ON tbl (last_updated DESC NULLS LAST);

Postgres 可以向后读取 btree 索引,但对于某些查询计划,添加 NULL 值的位置很重要。见:

Performance impact of view on aggregate function vs result set limiting

【讨论】:

我做到了。这就是我得到这个页面的方式:) 感谢您的回答。 SQLite3 添加了这个特性,在使用它之前,我想确保它与 PostgreSQL 兼容。原来这是现在的标准! 值得注意的是:NULLS FIRSTDESC 的默认值,NULLS LASTASC 的默认值。【参考方案2】:

您可以使用 CASE 语句创建自定义 ORDER BY。 CASE 语句检查您的条件并为满足该条件的行分配一个低于分配给不满足条件的行的值。 举个例子可能最容易理解:

  SELECT last_updated 
    FROM your_table 
ORDER BY CASE WHEN last_updated IS NULL THEN 0 ELSE 1 END, 
         last_updated ASC;

【讨论】:

还有,但您可能知道这一点,ASC 是默认排序顺序,因此您不一定需要输入。 NULLS FIRST 也是符合 ANSI 的先写入空值的方式。 @a_horse_with_no_name 这对我来说很有用,因为如果它不为空,我想忽略该值,然后按另一列排序。 (我对通知进行排序——首先是看不见的(然后是seenAt is null),但如果看到了,我会按createdAt instaed 排序) 同意;当我只想按是否存在值(在本例中为日期)进行排序时,我发现这很有用——然后再按另一个值进行排序。 NULLS FIRST 如果值非空,仍按实际值排序。这对我有用。谢谢! 这是最好的解决方案。可以与其他任何东西一起使用,例如deleted_at >= xyz time then 0 else 1 ...

以上是关于按 ASC 列排序,但首先是 NULL 值?的主要内容,如果未能解决你的问题,请参考以下文章

8)排序分组

Laravel Eloquent 模型按局部列和关系模型列值排序

#yyds干货盘点# 07 MySQL数据排序

Django REST ViewSet为Null-able列排序

首先按布尔列对数组进行排序,然后按字符串列排序

EasyClick 之 MySQL 排序