假设我有下表:
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
答案 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;