繰り返しになりますが、いくつかの「データ型」以上のものについては、crosstab()
を使用することをお勧めします :
SELECT * FROM crosstab(
$$SELECT DISTINCT ON (1, 2)
'max' AS "type", data_type, val
FROM tbl
ORDER BY 1, 2, val DESC$$
,$$VALUES ('Final Fantasy'), ('Quake 3'), ('World of Warcraft')$$)
AS x ("type" text, "Final Fantasy" int, "Quake 3" int, "World of Warcraft" int)
返品:
type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max | 500 | 1500 | 1200
基本の詳細説明:
PostgreSQLクロス集計クエリ
動的ソリューション
トリッキーなことは、これを完全に動的にすることです。 :それを機能させるために
- 不明な番号 列の数(この場合はdata_types)
- 不明な名前 (再びdata_types)
少なくともタイプ よく知られています:integer
この場合。
つまり、現在のPostgreSQL(9.3を含む)では不可能です。多態的なタイプの近似と、配列またはhstoreタイプの制限を回避する方法があります。あなたにとって十分かもしれません。しかし、それは厳密には不可能です 単一のSQLクエリの個々の列で結果を取得します。 SQLは型について非常に厳格であり、何を期待できるかを知りたがっています。
ただし 、 two で実行できます クエリ。最初のものは、使用する実際のクエリを作成します。上記の単純なケースに基づいて構築:
SELECT $f$SELECT * FROM crosstab(
$$SELECT DISTINCT ON (1, 2)
'max' AS "type", data_type, val
FROM tbl
ORDER BY 1, 2, val DESC$$
,$$VALUES ($f$ || string_agg(quote_literal(data_type), '), (') || $f$)$$)
AS x ("type" text, $f$ || string_agg(quote_ident(data_type), ' int, ') || ' int)'
FROM (SELECT DISTINCT data_type FROM tbl) x
これにより、実際に必要なクエリが生成されます。 同じトランザクション内で2番目のトランザクションを実行します 同時実行の問題を回避するため。
quote_literal()
の戦略的な使用に注意してください およびquote_ident()
あらゆる種類の不正な(列の)名前をサニタイズし、SQLインジェクションを防止します。 。
ドル相場の複数の層に混乱しないでください。これは、動的クエリを構築するために必要です。できるだけシンプルにしています。