Sekali lagi, untuk lebih dari beberapa "tipe data", saya sarankan untuk menggunakan 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)
Pengembalian:
type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max | 500 | 1500 | 1200
Penjelasan lebih lanjut untuk dasar-dasarnya:
Kueri Crosstab PostgreSQL
Solusi dinamis
Hal yang sulit adalah membuat sepenuhnya dinamis :untuk membuatnya bekerja untuk
- nomor tidak dikenal kolom (tipe_data dalam hal ini)
- dengan nama tidak dikenal (tipe_data lagi)
Setidaknya jenis terkenal:integer
dalam hal ini.
Singkatnya:itu tidak mungkin dengan PostgreSQL saat ini (termasuk 9.3). Ada perkiraan dengan tipe polimorfik dan cara untuk menghindari pembatasan dengan array atau tipe hstore. Mungkin cukup baik untuk Anda. Tapi itu sangat tidak mungkin untuk mendapatkan hasil dengan kolom individual dalam satu kueri SQL. SQL sangat kaku tentang tipe dan ingin tahu apa yang diharapkan kembali.
Namun , itu bisa dilakukan dengan dua pertanyaan. Yang pertama membangun kueri aktual untuk digunakan. Berdasarkan kasus sederhana di atas:
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
Ini menghasilkan kueri yang sebenarnya Anda butuhkan. Jalankan yang kedua di dalam transaksi yang sama untuk menghindari masalah konkurensi.
Perhatikan penggunaan strategis quote_literal()
dan quote_ident()
untuk membersihkan semua jenis nama ilegal (untuk kolom) dan mencegah injeksi SQL .
Jangan bingung dengan beberapa lapisan kutipan dolar. Itu diperlukan untuk membangun kueri dinamis. Saya membuatnya sesederhana mungkin.