IN()子句中的PostgreSQL ORDER BY值

时间:2011-07-25 21:35:38

标签: mysql arrays postgresql

好的,那里有一些关于如何做到这一点的答案。但所有答案都假设查询选择了全部。如果您有明确的选择,则方法不再有效。

请参阅此处了解该方法:Simulating MySQL's ORDER BY FIELD() in Postgresql

基本上我有

SELECT DISTINCT id 
FROM items 
WHERE id IN (5,2,9) 
ORDER BY
 CASE id
  WHEN 5 THEN 1 
  WHEN 2 THEN 2
  WHEN 9 THEN 3
 END

当然,这打破并说

  

“PGError:错误:对于SELECT DISTINCT,ORDER BY表达式必须   出现在选择列表“

有没有办法按照IN子句中值的顺序在PostgreSQL中命令查询结果?

4 个答案:

答案 0 :(得分:7)

您可以将其包装到派生表中:

SELECT *
FROM (
  SELECT DISTINCT id 
  FROM items 
  WHERE id IN (5,2,9) 
) t
ORDER BY
 CASE id
  WHEN 5 THEN 1 
  WHEN 2 THEN 2
  WHEN 9 THEN 3
 END

答案 1 :(得分:1)

来自documentation

  

提示:没有聚合表达式的分组可以有效地计算   列中的一组不同值。这也可以使用   DISTINCT子句(见Section 7.3.3)。

SQL查询:

SELECT id 
FROM items 
WHERE id IN (5,2,9) 
GROUP BY id
ORDER BY
    CASE id
        WHEN 5 THEN 1 
        WHEN 2 THEN 2
        WHEN 9 THEN 3
    END;

答案 2 :(得分:1)

环顾四周,我无法找到这个问题的完整解决方案。

我认为更好的解决方案是使用此查询

SELECT *
FROM items
WHERE id IN (5,2,9) 
ORDER BY idx(array[5,2,9]::integer[], items.id)

如果您使用的是PostgreSQL> = 9.2,则可以启用启用扩展程序的idx功能。

CREATE EXTENSION intarray;

否则您可以使用以下内容创建它:

CREATE OR REPLACE FUNCTION idx(anyarray, anyelement)
  RETURNS INT AS 
$$
  SELECT i FROM (
     SELECT generate_series(array_lower($1,1),array_upper($1,1))
  ) g(i)
  WHERE $1[i] = $2
  LIMIT 1;
$$ LANGUAGE SQL IMMUTABLE;

我真的建议在查询中使用::integer[],因为如果您动态创建数组,则可能没有导致ids(array[], items.id)的元素会导致PostgreSQL上出现异常。

答案 3 :(得分:0)

我在postgres PL / PGSQL中创建了这个函数,它更容易使用。

-- Function: uniqueseperategeomarray(geometry[], double precision)

-- DROP FUNCTION uniqueseperategeomarray(geometry[], double precision);

CREATE OR REPLACE FUNCTION manualidsort(input_id int, sort_array int[])
  RETURNS int AS
$BODY$
DECLARE
input_index int;
each_item int;
index int;
BEGIN
index := 1;
  FOREACH each_item IN ARRAY sort_array
  LOOP
    IF each_item = input_id THEN
      RETURN index;
    END IF;
    index := index+1;
  END LOOP;
END;
$BODY$
  LANGUAGE plpgsql;
ALTER FUNCTION manualidsort(int, int[])
  OWNER TO staff;

当你运行查询时,就这样......

SELECT * FROM my_table ORDER BY manualidsort(my_table_id, ARRAY[25, 66, 54])