2012-01-10 22 views
16

PostgreSQL配列の値の位置を取得する方法はありますか? Pythonには.index()メソッドがあり、PHPにはarray_search()ファンクションがありますが、PostgreSQLでこのような関数を見つけることはできません。それを行うストアドファンクションを作成する必要がありますか?私は、組み込み関数を使用して解決することを好む。PostgreSQL配列の値の位置を見つける

答えて

9

Since version 9.5には、配列キー(最初のオカレンスのみ)またはキー(すべてのオカレンス)を値で検索するための関数array_position()およびarray_positions()が組み込まれています。

これらの関数はanyarray型をサポートしています。

27

documentation recommendsgenerate_subscripts機能を使用しています。エミュレートのPHPのarray_search以下の機能:存在する場合

CREATE FUNCTION array_search(needle ANYELEMENT, haystack ANYARRAY) 
RETURNS INT AS $$ 
    SELECT i 
     FROM generate_subscripts($2, 1) AS i 
    WHERE $2[i] = $1 
    ORDER BY i 
$$ LANGUAGE sql STABLE; 

これは、最初のマッチのインデックスを返します。すべてのマッチが必要な場合は、RETURNS INTRETURNS SETOF INTに変更するだけです。この関数は、一致するものが見つからない場合はNULLを返します。

この関数は、1次元配列でのみ機能します。

また、array_search(NULL, a)は常に配列がnullの要素が含まれていても、NULLを返すことを念頭に置いてクマ:

> SELECT array_search(null, array[1, 2, null, 4]); 
array_search 
-------------- 

(1 row) 

SQLはNULL = NULL不明(すなわちNULL)であると見なしためです。 functions-comparisonを参照してください。あなたはarray_searchNULL要素を見つけることができるようにしたい場合は、

整数配列 のみについては
 WHERE $2[i] IS NOT DISTINCT FROM $1 
+0

+1 for generate_subscripts()と非常に完全な答えです。 –

+2

良い答え。 PostgreSQL 9.4で 'WITH ORDINAL'関数が追加されたときに、' unnest(the_array)WITH ORDINAL'と書くだけで、よりシンプルで効率的になります。たぶん私は9.4用の適切な 'idx'関数を書いて提出するべきです... –

4

 WHERE $2[i] = $1 

を変更するにはidx function from the intarray bundled extension大幅に高速化を使用することができます。

この関数は、すべての配列型をサポートするようには一般化されていませんが、残念ながら、他の配列に対しては非常に遅いSQLアプローチを採用しています。

関連する問題