ORDER BY 列,具有特定的 notnull 值 LAST

问题描述 投票:0回答:2

当我发现

NULLS LAST
时,我有点希望它可以在查询的
CASE
部分的
ORDER BY
语句中泛化为“X LAST”。

看来并非如此。

我试图按两列对表进行排序(简单),但以特定顺序获取输出(简单),其中一列的一个特定值出现在最后(完成了......丑陋)。

假设这些列是

zone
status
(不要怪我命名列
zone
- 我没有命名它们)。
status
仅采用 2 个值(“U”和“S”),而
zone
可以采用大约 100 个值中的任何一个。

zone
值的一个子集是(在伪正则表达式中)
IN[0-7]Z
,它们位于结果中的第一个。这很容易用
CASE
来完成。

zone
也可以采用值“Future”,该值应出现在结果中的最后。

以我典型的笨拙方式,我简单地将

CASE
值设置为 1000,如下所示:

group by zone, status
order by (
 case when zone='IN1Z' then 1
      when zone='IN2Z' then 2
      when zone='IN3Z' then 3
        .
        . -- other IN[X]Z etc
        .
      when zone = 'Future' then 1000
      else 11 -- [number of defined cases +1]
      end), zone, status

这可行,但显然是一种拼凑,我想知道是否可能有单行代码做同样的事情。
有没有更干净的方法来达到相同的结果?

sql postgresql null sql-order-by
2个回答
7
投票

Postgres 允许在 boolean

 子句中使用 
ORDER BY
 值。对于您的广义的“X LAST”

ORDER BY (my_column = 'X')

表达式的计算结果为

boolean
,这样排序:

false  -- think '0'
true   -- think '1'
null   -- NULLS LAST is default sort order

由于我们处理的是非空值,所以这就是我们所需要的。这是你的一句台词:

ORDER BY (zone = 'Future'), zone, status;

相关:


0
投票

我对 postgreSQL 不太熟悉,但我在 MS SQL Server 中遇到过类似的问题。据我所知,解决此类问题的唯一“好”方法是创建一个单独的区域值表并为每个区域值分配一个排序顺序。

例如,我们将表命名为 ZoneSequence:

Zone   | Sequence
------ | --------
IN1Z   |        1
IN2Z   |        2
IN3Z   |        3
Future |     1000

等等。然后,您只需将 ZoneSequence 连接到查询中,并按 Sequence 列排序(确保添加良好的索引!)。

此方法的好处是,当创建新的区域代码时很容易维护(很可能会如此)。

© www.soinside.com 2019 - 2024. All rights reserved.