为啥在 PostgreSQL 查询中排序 DESC 时 NULL 值排在第一位?

Posted

技术标签:

【中文标题】为啥在 PostgreSQL 查询中排序 DESC 时 NULL 值排在第一位?【英文标题】:Why do NULL values come first when ordering DESC in a PostgreSQL query?为什么在 PostgreSQL 查询中排序 DESC 时 NULL 值排在第一位? 【发布时间】:2014-01-24 08:54:31 【问题描述】:

在对查询进行降序或升序排序时,您什么时候需要先使用 NULLS?

在我看来,无论是升序还是降序排序,绝大多数的期望行为都是 NULLS LAST。相反,我们应该指定 NULLS FIRST。

【问题讨论】:

据说 SQL 标准没有指定 NULL 应该如何排序,所以这取决于将它写入 Postgres 的人:en.wikipedia.org/wiki/Order_by 为什么要先使用空值? @usr 你能解释一下“为什么在 PostgreSQL 查询中排序 DESC 时 NULL 值首先出现”这个问题吗?是基于意见的吗? @Bryan 我不认为总是首先或最后需要 NULL 是普遍的。如果 NULL 是重要的异常或缺失数据,您可能希望首先将它们展示给使用。如果它们代表不重要的案例,您希望最后显示它们。这完全取决于用例。 (有趣的是,您的问题包含“在我看来”这句话 :))。 如果空值是一个重要的异常 - 听起来像一个边缘情况。我的“问题描述”包含“我认为”,但问题没有。虽然我的描述是基于意见的,但问题不是“基于意见的问题”。 【参考方案1】:

简单的答案是因为编写 Postgres 的人就是这样设计它的。 To quote:

空值排序高于任何其他值。也就是说,升序排列时,空值排在最后,而降序排列时,空值排在开头。

这假定您已经指定了 ORDER BY 子句,如果您没有指定,则随机返回行。

如果指定了 ORDER BY 子句,则返回的行按指定的顺序排序。如果没有给出 ORDER BY,则以系统发现最快生成的任何顺序返回行。

【讨论】:

您引用了very old and unsupported version 8.2 的手册。【参考方案2】:

实际上,使用默认排序顺序 (ASCENDING) NULL 值排在 最后

逻辑规定使用DESCENDING 关键字反转排序顺序,因此在这种情况下首先出现NULL。

但最好的部分在最后:你可以选择你想要的方式:

Use the NULLS FIRST | LAST clause.

引用current manual,截至写作时的版本 9.3:

如果指定NULLS LAST,空值排在所有非空值之后 价值观;如果指定了NULLS FIRST,则空值排在所有之前 非空值。如果两者都没有指定,默认行为是 NULLS LASTASC 被指定或暗示时NULLS FIRSTDESC 被指定(因此,默认情况下就像空值更大一样 比非空值)。当指定USING 时,默认空值排序 取决于运算符是小于还是大于运算符。

我的大胆强调。

【讨论】:

是的,降序与升序相反是合乎逻辑的。同时,NULL 值“没有价值”,因此 NULL 值永远不应位于任何有序列表的顶部。 @Bryan:取决于你在做什么。有时,他们先走是有道理的。真正的问题是如何以及在何处将空数据放置在 btree 索引中。在 postgres 中,决定将它们放在最后,因此反向索引查找会使它们首先出现。

以上是关于为啥在 PostgreSQL 查询中排序 DESC 时 NULL 值排在第一位?的主要内容,如果未能解决你的问题,请参考以下文章

为啥按 count(lab_results.testid) desc 排序在 C# 中不起作用 - 但在 SQL Server 中很好?

mysql数据库多个表union all查询并排序的结果为啥错误

为啥在 PostgreSQL 存储过程中查询没有“结果数据的目标”?

PostgreSQL:如何在函数中并行运行查询?

PostgreSQL order by 排序问题

PostgreSQL入门