sql >> データベース >  >> RDS >> PostgreSQL

groupby句内の配列の結合

    UNION ALL

    UNION ALLで「カウンターピボット」することができます 最初:

    SELECT name, array_agg(c) AS c_arr
    FROM  (
       SELECT name, id, 1 AS rnk, col1 AS c FROM tbl
       UNION ALL
       SELECT name, id, 2, col2 FROM tbl
       ORDER  BY name, id, rnk
       ) sub
    GROUP  BY 1;
    

    後で要求した値の順序を生成するように適合されています。 マニュアル:

    大胆な強調鉱山。

    LATERAL サブクエリ VALUESを使用 式

    LATERAL Postgres 9.3が必要です またはそれ以降。

    SELECT t.name, array_agg(c) AS c_arr
    FROM  (SELECT * FROM tbl ORDER BY name, id) t
    CROSS  JOIN LATERAL (VALUES (t.col1), (t.col2)) v(c)
    GROUP  BY 1;
    

    同じ結果。テーブルを1回パスするだけで済みます。

    カスタム集計関数

    または これらの関連する回答で説明されているようなカスタム集計関数を作成できます:

    CREATE AGGREGATE array_agg_mult (anyarray)  (
        SFUNC     = array_cat
      , STYPE     = anyarray
      , INITCOND  = '{}'
    );
    

    次に、次のことができます。

    SELECT name, array_agg_mult(ARRAY[col1, col2] ORDER BY id) AS c_arr
    FROM   tbl
    GROUP  BY 1
    ORDER  BY 1;
    

    または、通常は高速ですが、標準のSQLではありません:

    SELECT name, array_agg_mult(ARRAY[col1, col2]) AS c_arr
    FROM  (SELECT * FROM tbl ORDER BY name, id) t
    GROUP  BY 1;
    

    追加されたORDER BY id (このような集計関数に追加できます)は、目的の結果を保証します:

    a | {1,2,3,4}
    b | {5,6,7,8}
    

    または、この代替案に興味があるかもしれません:

    SELECT name, array_agg_mult(ARRAY[ARRAY[col1, col2]] ORDER BY id) AS c_arr
    FROM   tbl
    GROUP  BY 1
    ORDER  BY 1;
    

    2次元配列を生成します:

    a | {{1,2},{3,4}}
    b | {{5,6},{7,8}}
    

    最後のものは、組み込みのarray_agg()に置き換えることができます(そして、より高速であるため、そうする必要があります!)。 Postgres 9.5 またはそれ以降-配列を集約する機能が追加されました:

    SELECT name, array_agg(ARRAY[col1, col2] ORDER BY id) AS c_arr
    FROM   tbl
    GROUP  BY 1
    ORDER  BY 1;
    

    同じ結果。 マニュアル:

    したがって、カスタム集計関数array_agg_mult()とまったく同じではありません。;



    1. 'YYYYMM'のようなPostgresqlのデフォルト値datestampを設定するにはどうすればよいですか?

    2. 戻りパラメータを使用してHibernateからOracle関数を呼び出す方法は?

    3. 名前が変数として渡されるテーブルからの選択

    4. PostgresqlからSolr6へのストップワードのロード