1

IN希望结果与传递给条件的顺序相同:

SELECT "id", 
       "field_a", 
       "field_b", 
       To_timestamp("on_dated") 
FROM   "test" 
WHERE  "id" IN ( 3, 1, 6, 2, 4 );

得到:

编号 | 字段_a | 字段_b | on_dated
-------------------------------------
1 | 维奈 | 中号 | 1383224064
2 | 阿莎 | F | 1383224064
3 | 沙市 | F | 1383224064
4 | 葡萄酒 | F | 1383224064
5 | 阿纳夫 | 中号 | 1383224064
6 | 贾扬特 | 中号 | 1383224064

期待:

编号 | 字段_a | 字段_b | on_dated
-------------------------------------
3 | 沙市 | F | 1383224064
1 | 维奈 | 中号 | 1383224064
6 | 贾扬特 | 中号 | 1383224064
2 | 阿莎 | F | 1383224064
4 | 葡萄酒 | F | 1383224064

试过:

SELECT "id", 
       "field_a", 
       "field_b", 
       To_timestamp("on_dated") 
FROM   "test" 
WHERE  "id" IN ( 3, 1, 6, 2, 4 ) 
ORDER  BY Field("id", '3', '1', '6', '2', '4');

但抛出错误:(


找到了更好的答案:

我还为此找到了一个更紧凑的答案:

SELECT * FROM "test"
WHERE "id" IN (3,1,6,2,4)
ORDER BY (id=3, id=1, id=6, id=2, id=4) DESC;
4

2 回答 2

1

根据定义,集合没有顺序。所以你原来的问题无法回答。它只能通过提供附加信息来工作(就像您在添加的解决方案中所做的那样)。

您可以传递@a_horse提供的数组。我建议在这种情况下使用,如下所示:PostgreSQL unnest() with element numbergenerate_subscripts()

即将推出的 Postgres 9.4(现在正在开发中)中有一个新功能可以让这变得简单:WITH ORDINALITY. 相同答案中的详细信息。

现在,您可以使用一组复合类型,包括行号:

SELECT t.*
FROM   test t
JOIN  (
    VALUES 
     (1, 3)
    ,(2, 1)
    ,(3, 6)
    ,(4, 2)
    ,(5, 5)
    ) val(rnk, test_id) USING (test_id)
ORDER  BY val.rnk;

->SQLfiddle 演示。

于 2013-11-01T01:41:41.093 回答
1

我能想到的唯一方法是这样的:

with numbers (id, sort_order) as (
  values 
     (3,1), 
     (1,2),
     (6,3),
     (2,4), 
     (4,5)
)
SELECT t.id, 
       t.field_a, 
       t.field_b, 
       to_timestamp(t.on_dated) 
FROM test
  JOIN numbers n on t.id = n.id
ORDER BY n.sort_order;

另一个稍微紧凑的版本:

with numbers (id, sort_order) as (
  select i, 
         row_number() over () 
  from unnest(ARRAY[3,1,6,2,4]) i
)
SELECT t.id, 
       t.field_a, 
       t.field_b, 
       to_timestamp(t.on_dated) 
FROM test
  JOIN numbers n on t.id = n.id
ORDER BY n.sort_order;

但是:这依赖于 unnest 总是以相同的顺序生成行的事实。我不完全确定情况总是如此。

如果你经常需要这个功能,你可以创建一个函数来做到这一点:

create or replace function get_index(to_find integer, elements int[])
  returns integer
as
$$
declare
  idx integer;
  x integer;
begin
  idx := 1;
  foreach x in array elements
  loop
    if to_find = x then
      return idx;
    end if;
    idx := idx + 1;
  end loop;
  return -1;
end;
$$
language plpgsql;

然后你可以写:

SELECT id, 
       field_a, 
       field_b, 
       to_timestamp(on_dated) 
FROM test
WHERE id = any (array[2,7,3,1])
ORDER BY get_index(id, array[2,7,3,1]);
于 2013-10-31T13:12:53.080 回答