【问题标题】:PostgreSQL: order by column, with specific NON-NULL value LASTPostgreSQL:按列排序,具有特定的非空值 LAST
【发布时间】:2015-08-24 23:31:46
【问题描述】:

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

似乎不是这样。

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

假设列是zone 和status(不要怪我为列命名zone - 我没有命名它们)。 status 只接受 2 个值('U' 和 'S'),而 zone 可以接受大约 100 个值中的任何一个。

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

zone 也可以取值 'Future',它应该出现在结果的最后。

以我典型的 kludgy-munge 方式,我简单地将 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

这行得通,但它显然是一个拼凑,我想知道是否可能有一个班轮做同样的事情。
有没有更简洁的方法来达到同样的效果?

【问题讨论】:

  • 缺少通常的嫌疑人:Postgres 版本和表定义(你在 psql 中使用 \d tbl 得到的),这将向我们显示确切的数据类型和 NOT NULL 约束。

标签: sql postgresql sql-order-by


【解决方案1】:

Postgres 允许在 ORDER BY 子句中使用 boolean 值,所以这是您的 generalised 'X LAST':

ORDER BY (my_column = 'X')

表达式的计算结果为boolean,结果值按以下方式排序:

FALSE (0)
TRUE (1)
NULL

由于我们处理的是非空值,这就是我们所需要的。这是你的单线:

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

相关:

【讨论】:

    【解决方案2】:

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

    例如,让我们调用表 ZoneSequence:

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

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

    这种方法的好处是在创建新的区号时很容易维护,因为它们很可能会这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-25
      • 2023-03-28
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多