Особената трудност е, че вашите данни не са готови за кръстосана таблица. Трябват ви данни във формата име_на_ред , категория , стойност . Можете да го получите с UNION
заявка:
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;
Но интелигентен LATERAL
заявката се нуждае само от сканиране на една таблица и ще бъде по-бърза:
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;
Свързани:
Използвайки простата форма на crosstab()
с 1 параметър с тази заявка като вход:
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);
Избройте имената на държавите в азбучен низходящ ред (както във вашата демонстрация). Това също предполага, че всички показатели са дефинирани NOT NULL
.
Ако едното или и двете не са, вместо това използвайте формата с 2 параметъра:
Добавяне на „сборен пакет“
т.е. общи суми за показател:
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'
е произволен етикет, който трябва да сортира последния по азбучен ред (или имате нужда от формата с 2 параметъра на crosstab()
).
Ако имате много от колони с показатели, може да искате да изградите динамично низа на заявката. Свързани:
- Как да извършите едно и също обобщаване на всяка колона, без да изброявате колоните?
- Динамично изпълнение на заявки в PL/ pgSQL
Също така имайте предвид, че предстоящият Postgres 9.5 (понастоящем бета) въвежда специален SQL клауза за ROLLUP
.
Свързани: