【PostgreSQL】縦持ちのデータを任意の列数の横持ちに変換する方法(折り返しあり)

スポンサーリンク

縦持ちのデータを任意の列数で横持ちに変換する方法です。
今回は例として、5列の横持ちにします。

やり方

前提

”食材マスタ”テーブルという以下のようなテーブルデータがあるとします。
これをidごとに横持ちにし、最大の列数を5列とし、5列以上の場合は折り返して2行目にします。

create table public."食材マスタ" (
  id integer not null
  , sub_id integer not null
  , "食材名" character varying(50) not null
  , primary key (id, sub_id)
);

↓サンプルデータ

SQL

SQLは以下です。
※列数を増やしたいときや減らしたいときは、以下SQL内の数値の5のところを変更する。
そして、MAXの行も増減させる。

WITH 食材マスタ_連番付与 AS ( 
    SELECT
        ID
        , 食材名
        , ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID) AS IDごとの連番 
    FROM
        食材マスタ
) 
, 食材マスタ_IDごとに行分け AS ( 
    SELECT
        ID
        , 食材名
        , IDごとの連番
        , ((IDごとの連番 - 1) / 5) + 1 AS IDごとの行番号 -- 1行目, 2行目...
    FROM
        食材マスタ_連番付与
) 
SELECT
    ID
    , IDごとの行番号
    , MAX(CASE WHEN (IDごとの連番 - 1) % 5 = 0 THEN 食材名 END) AS 食材名1
    , MAX(CASE WHEN (IDごとの連番 - 1) % 5 = 1 THEN 食材名 END) AS 食材名2
    , MAX(CASE WHEN (IDごとの連番 - 1) % 5 = 2 THEN 食材名 END) AS 食材名3
    , MAX(CASE WHEN (IDごとの連番 - 1) % 5 = 3 THEN 食材名 END) AS 食材名4
    , MAX(CASE WHEN (IDごとの連番 - 1) % 5 = 4 THEN 食材名 END) AS 食材名5 
    -- 列数を変更したいときは、上記の行を増減させる
FROM
    食材マスタ_IDごとに行分け 
GROUP BY
    ID
    , IDごとの行番号 
ORDER BY
    ID
    , IDごとの行番号;

結果は以下のようになります。IDごとに最大5列(5列以上の場合は次の行に折り返し)

コメント

タイトルとURLをコピーしました