nut*_*ker 146 sql postgresql sql-order-by sql-in
我在PostgreSQL 8.3中有一个简单的SQL查询,可以获取一堆注释.我在子句中为构造提供了一个值的排序列表:IN
WHERE
SELECT * FROM comments WHERE (comments.id IN (1,3,2,4));
Run Code Online (Sandbox Code Playgroud)
这将以任意顺序返回注释,在我碰巧是ids之类的1,2,3,4
.
我希望结果行像IN
构造中的列表一样排序:(1,3,2,4)
.
怎么实现呢?
小智 94
你可以很容易地使用(在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
Run Code Online (Sandbox Code Playgroud)
小智 62
仅仅因为它很难找到并且必须传播:在mySQL中,这可以做得更简单,但我不知道它是否适用于其他SQL.
SELECT * FROM `comments`
WHERE `comments`.`id` IN ('12','5','3','17')
ORDER BY FIELD(`comments`.`id`,'12','5','3','17')
Run Code Online (Sandbox Code Playgroud)
Erw*_*ter 44
在Postgres 9.4或更高版本中,这可能是最简单和最快的:
SELECT c.*
FROM comments c
JOIN unnest('{1,3,2,4}'::int[]) WITH ORDINALITY t(id, ord) USING (id)
ORDER BY t.ord;
Run Code Online (Sandbox Code Playgroud)
我们不需要子查询,我们可以像表一样使用set-returns函数.
一些客户端可能更容易实现传递数组而不是ARRAY构造函数的字符串文字.
详细说明:
van*_*con 43
我认为这种方式更好:
SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4))
ORDER BY id=1 DESC, id=3 DESC, id=2 DESC, id=4 DESC
Run Code Online (Sandbox Code Playgroud)
a_h*_*ame 33
使用Postgres 9.4,这可以做得更短:
select c.*
from comments c
join (
select *
from unnest(array[43,47,42]) with ordinality
) as x (id, ordering) on c.id = x.id
order by x.ordering
Run Code Online (Sandbox Code Playgroud)
无需为每个值手动分配/维护位置.
使用Postgres 9.6,可以使用array_position()
以下方法完成:
with x (id_list) as (
values (array[42,48,43])
)
select c.*
from comments c, x
where id = any (x.id_list)
order by array_position(x.id_list, c.id);
Run Code Online (Sandbox Code Playgroud)
使用CTE使得值列表仅需要指定一次.如果这不重要,这也可以写成:
select c.*
from comments c
where id in (42,48,43)
order by array_position(array[42,48,43], c.id);
Run Code Online (Sandbox Code Playgroud)
Car*_*ier 29
在Postgres中执行此操作的另一种方法是使用该idx
功能.
SELECT *
FROM comments
ORDER BY idx(array[1,3,2,4], comments.id)
Run Code Online (Sandbox Code Playgroud)
不要忘记首先创建idx
函数,如下所述:http://wiki.postgresql.org/wiki/Array_Index
Clo*_*eto 18
在Postgresql中:
select *
from comments
where id in (1,3,2,4)
order by position(id::text in '1,3,2,4')
Run Code Online (Sandbox Code Playgroud)