La difficoltà speciale è che i tuoi dati non sono pronti per la tabulazione incrociata. Hai bisogno dei dati nel modulo nome_riga , categoria , valore . Puoi ottenerlo con un UNION
domanda:
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;
Ma un intelligente LATERAL
query richiede solo una scansione di una singola tabella e sarà più veloce:
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;
Correlati:
- Qual è la differenza tra LATERAL e una sottoquery in PostgreSQL?
- SELEZIONARE DISTINCT su più colonne
Usando la semplice forma di crosstab()
con 1 parametro con questa query come 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);
Elenca i nomi dei paesi in ordine alfabetico decrescente (come nella tua demo). Ciò presuppone anche che tutte le metriche siano definite NOT NULL
.
Se uno o entrambi non sono il caso, utilizzare invece il modulo a 2 parametri:
Aggiungi "rollup"
Cioè. totali per metrica:
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'
è un'etichetta arbitraria, che deve essere ordinata per ultima in ordine alfabetico (oppure è necessaria la forma a 2 parametri di crosstab()
).
Se hai lotti delle colonne delle metriche, potresti voler creare la stringa di query in modo dinamico. Correlati:
- Come eseguire la stessa aggregazione su ogni colonna, senza elencare le colonne?
- Esecuzione dinamica delle query in PL/ pgSQL
Si noti inoltre che il prossimo Postgres 9.5 (attualmente beta) introduce un Clausola SQL per ROLLUP
.
Correlati: