PostgreSQL : crosstabの使い方
遅れましたがcrosstab関数の紹介です。
まず前回使ったコードをおさらいしましょう。
select * from crosstab('select データ識別番号,連番,ペイロード9 from ff1test Where コード = ''A006040''', 'select m from generate_series(1,10) m') AS( データ識別番号 int, 病名1 text, 病名2 text, 病名3 text, 病名4 text, 病名5 text, 病名6 text, 病名7 text, 病名8 text, 病名9 text, 病名10 text);
ではcrosstab部分の構造を見ていきましょう。 この関数は、3つの部分を持ちます。
データソースを取り出すSQL構文
整形したい表に必要なカテゴリ項目の列挙
2で列挙した項目の定義付け
1) については、ドキュメントに
source_sqlは元となるデータ集合を生成するSQL文です。 このSQL文はrow_name列を1つcategory列を1つ、value列を1つ返さなければなりません。
とあります。
crosstab('select データ識別番号,連番,ペイロード9 from ff1test Where コード = ''A006040''',
の部分ですね。
この例では、データ識別番号
がrow_name
、連番
がcategory列
、ペイロード9
がvalue列
です。
2)は
'select m from generate_series(1,10) m')
の部分ですが、見ればわかる通り、ほぼドキュメントの例の引き写しです。ペイロード9に保持される併存病名は上限10なので、1から10の数列を用意します。
仕組みとしては、カテゴリー列を持つデータを用意して、カテゴリー列を元に横向きに並び替える、という動きをします。本来はクロス集計に用いる関数なので、このカテゴリ列ごとに集計を行うのですが、今回は単にデータを横持ちにするだけです。
3)で、出来上がる表のデータ形式を定義します。
AS( データ識別番号 int, 病名1 text, 病名2 text, 病名3 text, 病名4 text, 病名5 text, 病名6 text, 病名7 text, 病名8 text, 病名9 text, 病名10 text);
テーブルの定義文にそっくりですね。
今回は普通にintとtextを使いました。
以上でざっと紹介を終えますが、公式ドキュメントとにらめっこするのは必須でしょう。
あんまり複雑になるようならスクリプトで加工した方がいいと思いますが、今回のように「複数行にまたがるデータを1行に圧縮して欲しい」というケースでは大変便利です