条带化PostgreSQL结果集的顺序

时间:2012-05-02 17:58:09

标签: sql postgresql sorting sql-order-by

假设我有下表:

create temp table test (id serial, number integer);
insert into test (number) 
values (5), (4), (3), (2), (1), (0);

如果按数字降序排序,我得到:

select * from test order by number desc;
id | number
---+--------
 1 | 5
 2 | 4
 3 | 3
 4 | 2
 5 | 1
 6 | 0

如果我按数字升序排序,我会得到:

select * from test order by number asc;

6 | 0
5 | 1
4 | 2
3 | 3
2 | 4
1 | 5

如何对订单进行条带化以使其在每行的升序和降序之间交替? 例如:

6 | 0   or   1 | 5
1 | 5        6 | 0
5 | 1        2 | 4
2 | 4        5 | 1
4 | 2        3 | 3
3 | 3        4 | 2

2 个答案:

答案 0 :(得分:5)

更新

WITH x AS (
    SELECT *
         , row_number() OVER (ORDER BY number) rn_up
         , row_number() OVER (ORDER BY number DESC) rn_down
    FROM   test
    )
SELECT id, number
FROM   x
ORDER  BY LEAST(rn_up, rn_down), number;

或者:

...
ORDER  BY LEAST(rn_up, rn_down), number  DESC;

从更大的数字开始。

我最初有两个CTE,但一个就够了 - 更简单,更快。

答案 1 :(得分:2)

或者像这样(类似于已经给出的答案,但稍微短一些:)

WITH x AS (
    SELECT *, row_number() OVER (ORDER BY number) rn, count(*) over () as c
    FROM test
    )
SELECT id, number
FROM x 
ORDER BY ABS((c + 1.5) / 2 - rn) DESC;

如果需要相反的顺序,那么它应该是

ORDER BY ABS((c + 0.5) / 2 - rn) DESC;