我在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)。 如何实现这一目标?


当前回答

SELECT * FROM "comments" JOIN (
  SELECT 1 as "id",1 as "order" UNION ALL 
  SELECT 3,2 UNION ALL SELECT 2,3 UNION ALL SELECT 4,4
) j ON "comments"."id" = j."id" ORDER BY j.ORDER

或者如果你喜欢恶而不是善:

SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4))
ORDER BY POSITION(','+"comments"."id"+',' IN ',1,3,2,4,')

其他回答

通过进一步研究,我发现了这个解决方案:

SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4)) 
ORDER BY CASE "comments"."id"
WHEN 1 THEN 1
WHEN 3 THEN 2
WHEN 2 THEN 3
WHEN 4 THEN 4
END

然而,这似乎相当冗长,并且对于大型数据集可能会有性能问题。 有人能就这些问题发表评论吗?

SELECT * FROM "comments" JOIN (
  SELECT 1 as "id",1 as "order" UNION ALL 
  SELECT 3,2 UNION ALL SELECT 2,3 UNION ALL SELECT 4,4
) j ON "comments"."id" = j."id" ORDER BY j.ORDER

或者如果你喜欢恶而不是善:

SELECT * FROM "comments" WHERE ("comments"."id" IN (1,3,2,4))
ORDER BY POSITION(','+"comments"."id"+',' IN ',1,3,2,4,')

在Postgres中另一种方法是使用idx函数。

SELECT *
FROM comments
ORDER BY idx(array[1,3,2,4], comments.id)

不要忘记首先创建idx函数,如下所述:http://wiki.postgresql.org/wiki/Array_Index

你可以很容易地使用(在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

这里有另一个解决方案,它使用了一个常量表(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

但我不确定这是表现性的。

我现在有一堆答案了。我可以得到一些投票和评论,这样我就知道哪一个是赢家!

谢谢大家:-)