Zvláštní problém spočívá v tom, že vaše data nejsou připravena pro křížovou tabulku. Potřebujete údaje ve tvaru název_řádku , kategorie , hodnota . Můžete to získat pomocí UNION
dotaz:
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 chytrý LATERAL
dotaz potřebuje pouze prohledání jedné tabulky a bude rychlejší:
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;
Související:
Pomocí jednoduchého tvaru crosstab()
s 1 parametrem s tímto dotazem jako vstupem:
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);
Uveďte názvy zemí v abecedním sestupném pořadí (jako ve vaší ukázce). To také předpokládá, že všechny metriky jsou definovány NOT NULL
.
Pokud jeden nebo oba neplatí, použijte místo toho formulář se 2 parametry:
Přidat souhrn
Tj. součty za metriku:
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'
je libovolný štítek, který musí seřadit na posledním místě podle abecedy (nebo potřebujete 2parametrovou formu crosstab()
).
Pokud máte spoustu sloupců metrik, možná budete chtít vytvořit řetězec dotazu dynamicky. Související:
- Jak provést stejnou agregaci pro každý sloupec, aniž byste sloupce vypisovali?
- Dynamické provádění dotazů v PL/ pgSQL
Všimněte si také, že nadcházející Postgres 9.5 (aktuálně beta) zavádí vyhrazený klauzule SQL pro ROLLUP
.
Související: