Szczególna trudność polega na tym, że Twoje dane nie są gotowe do tabeli krzyżowej. Potrzebujesz danych w formacie nazwa_wiersza , kategoria , wartość . Możesz to uzyskać za pomocą UNION
zapytanie:
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;
Ale sprytny LATERAL
zapytanie wymaga tylko pojedynczego skanowania tabeli i będzie szybsze:
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;
Powiązane:
Używając prostej formy crosstab()
z 1 parametrem z tym zapytaniem jako danymi wejściowymi:
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);
Lista nazw krajów w kolejności alfabetycznej malejącej (tak jak w demonstracji). Zakłada się również, że wszystkie metryki są zdefiniowane NOT NULL
.
Jeśli jeden lub oba nie są w tym przypadku, użyj zamiast tego formularza 2-parametrowego:
Dodaj „podsumowanie”
Tj. sumy na metrykę:
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'
to dowolna etykieta, która musi być posortowana alfabetycznie (lub potrzebna jest dwuparametrowa forma crosstab()
).
Jeśli masz dużo kolumn metryk, możesz chcieć dynamicznie skompilować ciąg zapytania. Powiązane:
- Jak wykonać tę samą agregację w każdej kolumnie, nie wymieniając kolumn?
- Wykonywanie zapytań dynamicznie w PL/ pgSQL
Należy również pamiętać, że nadchodzący Postgres 9.5 (obecnie beta) wprowadza dedykowany Klauzula SQL dla ROLLUP
.
Powiązane: