web-dev-qa-db-ja.com

array_aggとunnestを組み合わせる

データセット(GINvaluesインデックスを使用)を指定:

key | values
-------------
 1  | {4,2,1}
 1  | {2,5}
 2  | {4,1,3}

配列を集約したい:

key | values
-------------
 1  | {4,2,1,5}
 2  | {4,1,3}

私の最初の考えはうまくいきませんでした:

SELECT key, array_agg(DISTINCT unnest(values)) AS values FROM data GROUP BY key

[0A000]エラー:集合関数呼び出しにセットを返す関数呼び出しを含めることはできません
ヒント:セットを返す関数をLATERAL FROMアイテムに移動できる場合があります。

LATERAL FROMに精通していないため、希望する出力を実現する方法がわかりません。

3
OrangeDog

サブクエリでネストを解除する必要があります:

_select d."key", array_agg(distinct x.v) 
from data d
  cross join lateral unnest(d."values") as x(v)
group by d."key";
_

戻り関数の設定(unnest()など)は、通常、クエリのfrom部分で使用する必要があります。ただし、テーブルの列を参照できるようにするには、 ラテラル結合 が必要です。

from data cross join lateral unnest(...)は、クロス結合も生成するfrom data, unnest(...)を明示的に記述する方法です。しかし、偶然ではなく、実際にクロス結合を作成するつもりであったことを文書化するために、明示的な_cross join_演算子を使用することを好みます。

ただし、要素の順序は保持されません。

オンラインの例: https://rextester.com/TVIDB57711