【问题标题】:Sorting null values after all others, except special将空值排在所有其他值之后,特殊除外
【发布时间】:2014-03-20 10:50:03
【问题描述】:

我有一个带有可选排序字段的 PostgreSQL 项目表:

CREATE TABLE tasks (
  id     integer  PRIMARY KEY DEFAULT nextval('f_seq'),
  f_id   integer  REFERENCES fixins,
  name   text     NOT NULL,
  sort   integer
);

我希望没有sort 值的任务排在所有其他任务之后,但有一个例外:如果sort = -1 我希望它排在那些之后。因此,例如,给定这些值:

id | f_id |   name   | sort
---+------+----------+-------
 1 |    1 | zeta     |    -1
 2 |    1 | alpha    |     1
 3 |    1 | gamma    |     3
 4 |    1 | beta     |     2
 5 |    1 | delta    |     
 6 |    1 | epsilon  |     

我希望它们排序为:alphabetagammadeltaepsilonzeta

我知道我可以使用ORDER BY COALESCE(sort,99999) 在非空值之后排序空值,但我怎样才能让特殊的-1 值出现在它们之后?

【问题讨论】:

  • 试试order by coalesce(order, 0)
  • 呃,对不起,误读了这个问题。

标签: sql postgresql sorting null sql-order-by


【解决方案1】:
SELECT name FROM tasks
  WHERE f_id=1
  ORDER BY
    CASE COALESCE(sort,88888)
      WHEN -1 THEN 99999
      ELSE         COALESCE(sort,88888)
    END,
    id;

仍在寻找一种更优雅的方式来只合并一次,而不选择它。

【讨论】:

    【解决方案2】:

    更简单:

    SELECT *
    FROM   tasks
    ORDER  BY (sort IS NOT DISTINCT FROM -1), sort;
    

    怎么做?

    Postgres 有一个正确的 boolean 类型(与其他一些 RDBMS 不同)。您可以像按任何其他数据类型一样按它排序。它可以像任何其他数据类型一样为 NULL。默认排序顺序为:

    FALSE (0)
    TRUE (1)
    NULL
    

    (sort IS NOT DISTINCT FROM -1) 对除 -1 之外的所有值计算为 FALSE - 它计算 TRUE 并排在最后。只需将sort 添加为辅助ORDER BY 项即可。

    等效替代:

    SELECT *
    FROM   tasks
    ORDER  BY (sort IS DISTINCT FROM -1) DESC, sort;
    

    db小提琴here
    sqlfiddle

    【讨论】:

    • 这仍然需要合并来将空值放在非空值之后,是吗?
    • @Phrogz:不,NULL 默认按升序对 after 非空值进行排序 - 如解释中所述。我加了一个小提琴。
    • 不,你不需要合并。
    • @Phrogz:好的,对不起,我倒过来了。现在把它理顺了。
    • 谢谢!比我的回答优雅得多。
    猜你喜欢
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多