Kesulitan khusus adalah bahwa data Anda belum siap untuk tabulasi silang. Anda memerlukan data dalam bentuk row_name , kategori , nilai . Anda bisa mendapatkannya dengan UNION
permintaan:
SELECT 'metric1' AS metric, country_code, metric1 FROM tbl1
UNION ALL
SELECT 'metric2' AS metric, country_code, metric2 FROM tbl1
UNION ALL
SELECT 'metric3' AS metric, country_code, metric3 FROM tbl1
ORDER BY 1, 2 DESC;
Tapi LATERAL
yang cerdas kueri hanya membutuhkan pemindaian tabel tunggal dan akan lebih cepat:
SELECT x.metric, t.country_code, x.val
FROM tbl1 t
, LATERAL (VALUES
('metric1', metric1)
, ('metric2', metric2)
, ('metric3', metric3)
) x(metric, val)
ORDER BY 1, 2 DESC;
Terkait:
Menggunakan bentuk sederhana crosstab()
dengan 1 parameter dengan kueri ini sebagai input:
SELECT * FROM crosstab(
$$SELECT x.metric, t.country_code, x.val
FROM tbl1 t
, LATERAL (VALUES
('metric1', metric1)
, ('metric2', metric2)
, ('metric3', metric3)
) x(metric, val)
ORDER BY 1, 2 DESC$$
)
AS ct (metric text, us int, uk int, fr int);
Cantumkan nama negara dalam urutan abjad (seperti di demo Anda). Ini juga mengasumsikan semua metrik ditentukan NOT NULL
.
Jika salah satu atau keduanya tidak demikian, gunakan formulir 2 parameter sebagai gantinya:
Tambahkan "rollup"
Yaitu. total per metrik:
SELECT * FROM crosstab(
$$SELECT x.metric, t.country_code, x.val
FROM (
TABLE tbl1
UNION ALL
SELECT 'zzz_total', sum(metric1)::int, sum(metric2)::int, sum(metric3)::int -- etc.
FROM tbl1
) t
, LATERAL (VALUES
('metric1', metric1)
, ('metric2', metric2)
, ('metric3', metric3)
) x(metric, val)
ORDER BY 1, 2 DESC$$
)
AS ct (metric text, total int, us int, uk int, fr int);
'zzz_total'
adalah label arbitrer, yang harus diurutkan terakhir menurut abjad (atau Anda memerlukan bentuk 2 parameter crosstab()
).
Jika Anda memiliki banyak kolom metrik, Anda mungkin ingin membuat string kueri secara dinamis. Terkait:
- Bagaimana cara melakukan agregasi yang sama pada setiap kolom, tanpa mencantumkan kolom?
- Menjalankan kueri secara dinamis di PL/ pgSQL
Perhatikan juga bahwa Postgres 9.5 yang akan datang (saat ini beta) memperkenalkan klausa SQL untuk ROLLUP
.
Terkait: