我在PostgreSQL 8.3中有一个简单的SQL查询,它抓取了一堆注释。我在WHERE子句中为IN构造提供了一个排序的值列表:
SELECT * FROM comments WHERE (comments.id IN (1,3,2,4));
这将以任意顺序返回注释,在my中恰好是id,如1,2,3,4。
我希望结果行像in结构中的列表一样排序:(1,3,2,4)。 如何实现这一目标?
我在PostgreSQL 8.3中有一个简单的SQL查询,它抓取了一堆注释。我在WHERE子句中为IN构造提供了一个排序的值列表:
SELECT * FROM comments WHERE (comments.id IN (1,3,2,4));
这将以任意顺序返回注释,在my中恰好是id,如1,2,3,4。
我希望结果行像in结构中的列表一样排序:(1,3,2,4)。 如何实现这一目标?
当前回答
这里有另一个解决方案,它使用了一个常量表(http://www.postgresql.org/docs/8.3/interactive/sql-values.html):)
SELECT * FROM comments AS c,
(VALUES (1,1),(3,2),(2,3),(4,4) ) AS t (ord_id,ord)
WHERE (c.id IN (1,3,2,4)) AND (c.id = t.ord_id)
ORDER BY ord
但我不确定这是表现性的。
我现在有一堆答案了。我可以得到一些投票和评论,这样我就知道哪一个是赢家!
谢谢大家:-)
其他回答
无序列,只适用于8.4:
select * from comments c
join
(
select id, row_number() over() as id_sorter
from (select unnest(ARRAY[1,3,2,4]) as id) as y
) x on x.id = c.id
order by x.id_sorter
你可以很容易地使用(在PostgreSQL 8.2中引入)VALUES(),()。
语法是这样的:
select c.*
from comments c
join (
values
(1,1),
(3,2),
(2,3),
(4,4)
) as x (id, ordering) on c.id = x.id
order by x.ordering
让我们对已经说过的内容有一个直观的印象。例如,你有一个带有一些任务的表:
SELECT a.id,a.status,a.description FROM minicloud_tasks as a ORDER BY random();
id | status | description
----+------------+------------------
4 | processing | work on postgres
6 | deleted | need some rest
3 | pending | garden party
5 | completed | work on html
并且您希望按状态对任务列表进行排序。 status是一个字符串值列表:
(processing, pending, completed, deleted)
诀窍是给每个状态值一个整数,并以数字顺序排列列表:
SELECT a.id,a.status,a.description FROM minicloud_tasks AS a
JOIN (
VALUES ('processing', 1), ('pending', 2), ('completed', 3), ('deleted', 4)
) AS b (status, id) ON (a.status = b.status)
ORDER BY b.id ASC;
这就导致:
id | status | description
----+------------+------------------
4 | processing | work on postgres
3 | pending | garden party
5 | completed | work on html
6 | deleted | need some rest
信贷@user80168
相比使用序列的版本略有改进,我认为:
CREATE OR REPLACE FUNCTION in_sort(anyarray, out id anyelement, out ordinal int)
LANGUAGE SQL AS
$$
SELECT $1[i], i FROM generate_series(array_lower($1,1),array_upper($1,1)) i;
$$;
SELECT
*
FROM
comments c
INNER JOIN (SELECT * FROM in_sort(ARRAY[1,3,2,4])) AS in_sort
USING (id)
ORDER BY in_sort.ordinal;
在Postgres中另一种方法是使用idx函数。
SELECT *
FROM comments
ORDER BY idx(array[1,3,2,4], comments.id)
不要忘记首先创建idx函数,如下所述:http://wiki.postgresql.org/wiki/Array_Index