2011-07-25 24 views
5

これを行う方法についていくつかの回答があります。しかし、すべての答えは、クエリがすべてを選択していると仮定しています。異なる選択がある場合、メソッドはもはや機能しません。IN()句のPostgreSQL ORDER BYの値

は、その方法についてはこちらをご覧ください: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: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list"

を言うPostgreSQLでは、クエリの結果を注文する方法はありますIN節の値の順番で?

+0

"_ORDER BY式はselect list_に指定する必要があります" - 式をSELECTリストに移動するだけです:) – Karolis

答えて

7

あなたは派生テーブルにそれをラップすることができます:documentationから

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

Tip: Grouping without aggregate expressions effectively calculates the set of distinct values in a column. This can also be achieved using the DISTINCT clause (see 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; 
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]) 
0

は周りを見る私はこの質問への完全なソリューションを見つけることができませんでした。

私はよりよい解決策は、あなたは、PostgreSQL> = 9.2を使用している場合は、拡張機能を有効にするIDX機能を有効にすることができ、このクエリ

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

を使用することだと思います。

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; 

をあなたが動的に配列を作成している場合、それはids(array[], items.id)が生じ要素を持たないことがあるので、私は本当にクエリで::integer[]を使用することをお勧めPostgreSQLの例外が発生します。