7

PostgreSQLは、どこからでも配列の添え字を処理できます。
5から7までの添え字を持つ3つの要素を持つ配列を作成するこの例を考えてみましょう。

SELECT '[5:7]={1,2,3}'::int[];

戻り値:

[5:7]={1,2,3}

下付き文字で最初の要素を取得します5

SELECT ('[5:7]={1,2,3}'::int[])[5];

1次元配列を正規化して、配列の添え字1から始めたいと思います。
私が思いつくことができる最高のもの:

SELECT ('[5:7]={1,2,3}'::int[])[array_lower('[5:7]={1,2,3}'::int[], 1):array_upper('[5:7]={1,2,3}'::int[], 1)]

同じ、読みやすい:

WITH   cte(a) AS (SELECT '[5:7]={1,2,3}'::int[])
SELECT a[array_lower(a, 1):array_upper(a, 1)]
FROM   cte;

よりシンプル/高速、または少なくともよりエレガントな方法を知っていますか?

Postgres9.5の古いソリューションのベンチマーク

ここでdb<>フィドル

Postgres14の新しいソリューションを含むベンチマーク

ここでdb<>フィドル

4

3 に答える 3

6

醜いより簡単な方法がありますが、技術的に正しいと思います。計算された境界を持つ正確なスライスではなく、配列から可能な限り最大のスライスを抽出します。2つの関数呼び出しを回避します。

例:

select ('[5:7]={1,2,3}'::int[])[-2147483648:2147483647];

結果:

  int4   
---------
 {1,2,3}
于 2012-08-17T19:49:36.313 に答える
6

最終的に、Postgres9.6でよりエレガントなものが登場しましマニュアル:

スライス指定子のlower-boundおよび/または を省略することができます。upper-bound欠落している境界は、配列の添え字の下限または上限に置き換えられます。例えば:

だから今は簡単です:

SELECT my_arr[:];

私の例の配列リテラルでは、構文を明確にするために括弧を囲む必要があります::

SELECT ('[5:7]={1,2,3}'::int[])[:];

ハードコードされた最大配列の添え字を使用したDanielのソリューションとほぼ同じパフォーマンス-これは、Postgres9.5以前で使用する方法です。

于 2017-06-09T02:12:19.640 に答える
3

これがすでにカバーされているかどうかはわかりませんが、次のようになります。

SELECT array_agg(v) FROM unnest('[5:7]={1,2,3}'::int[]) AS a(v);

パフォーマンスをテストするidには、テストテーブルに列を追加する必要がありました。遅い。

于 2012-08-17T21:57:35.810 に答える