除了特殊值之外,对所有其他值排序空值

时间:2014-02-19 20:34:20

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

我有一个带有可选订购字段的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值呢?

2 个答案:

答案 0 :(得分: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)评估除FALSE以外的所有值的-1 - 评估TRUE并排序最后。只需将sort添加为辅助ORDER BY项。

等效替代方案:

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

SQL Fiddle.

答案 1 :(得分:0)

SELECT name FROM tasks
  WHERE f_id=1
  ORDER BY
    CASE COALESCE(sort,88888)
      WHEN -1 THEN 99999
      ELSE         COALESCE(sort,88888)
    END,
    id;

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