列名を変更しましたgroup
grp
へ group
予約語
です。 PostgresおよびすべてのSQL標準で使用されており、識別子として使用しないでください。
私はあなたの質問を次のように理解しています:
2つの配列を同じ並べ替え順序で並べ替えて、同じ要素の位置が両方の配列の同じ行に対応するようにします。
サブクエリを使用する またはCTE 集計する前に行を並べ替えます。
SELECT id, array_agg(grp) AS grp, array_agg(dt) AS dt
FROM (
SELECT *
FROM tbl
ORDER BY id, grp, dt
) x
GROUP BY id;
それは速い 個別のORDER BY
を使用するよりも 集計関数の句
array_agg()
@Mostyのデモ
のように (そしてこれはPostgreSQL 9.0以来存在しています)。また、ほとんどの場合、質問の解釈が異なり、適切なツールを使用して解釈します。
はORDER BY
です サブクエリで安全ですか?
そうです、この例では安全です。
サブクエリなし
本当に必要の場合 サブクエリなしのソリューション 、次のことができます:
SELECT id
, array_agg(grp ORDER BY grp)
, array_agg(dt ORDER BY grp, dt)
FROM tbl
GROUP BY id;
ORDER BY grp, dt
に注意してください 。 dt
で並べ替えます 結びつきを断ち切り、ソート順を明確にすることに加えて。 grp
には必要ありません 、しかし。
ウィンドウ関数<を使用して、これを行うまったく異なる方法もあります。 / a> :
SELECT DISTINCT ON (id)
id
, array_agg(grp) OVER w AS grp
, array_agg(dt) OVER w AS dt
FROM tbl
WINDOW w AS (PARTITION BY id ORDER BY grp, dt
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
ORDER BY id;
DISTINCT ON (id)
に注意してください DISTINCT
だけでなく これは同じ結果を生成しますが、追加の並べ替えが必要ないため、1桁高速に実行されます。
私はいくつかのテストを実行しましたが、これは他の2つのソリューションとほぼ同じ速さです。予想通り、サブクエリバージョンは依然として最速でした。 EXPLAIN ANALYZE
でテストする 自分の目で確かめてください。