Den særlige vanskelighed er, at dine data ikke er klar til krydstabulering. Du har brug for data i formen rækkenavn , kategori , værdi . Du kan få det med en UNION
forespørgsel:
VÆLG 'metric1' AS metric, country_code, metric1 FROM tbl1UNION ALLSELECT 'metric2' AS metric, country_code, metric2 FROM tbl1UNION ALLSELECT 'metric3' AS metric, country_code, metric3 FROM tbl1ORDER BY 1, 2 DESC;
Men en smart LATERAL
forespørgslen behøver kun en enkelt tabelscanning og vil være hurtigere:
SELECT x.metric, t.country_code, x.valFROM tbl1 t , LATERAL (VÆRDIER ('metric1', metric1) , ('metric2', metric2) , ('metric3', metric3) ) x( metrisk, val)ORDER BY 1, 2 DESC;
Relateret:
- Hvad er forskellen mellem LATERAL og en underforespørgsel i PostgreSQL?
- VÆLG DISTINCT på flere kolonner
Ved at bruge den simple form for crosstab()
med 1 parameter med denne forespørgsel som input:
SELECT * FROM crosstab( $$SELECT x.metrisk, t.country_code, x.val FROM tbl1 t , LATERAL (VÆRDIER ('metric1', metric1), ('metric2', metric2) , (' metric3', metric3) ) x(metrisk, val) BESTIL EFTER 1, 2 DESC$$ )AS ct (metrisk tekst, us int, uk int, fr int);
Angiv landenavne i alfabetisk faldende rækkefølge (som i din demo). Dette forudsætter også, at alle metrics er defineret IKKE NULL
.
Hvis den ene eller begge ikke er tilfældet, skal du bruge 2-parameter-formularen i stedet:
Tilføj "oprulning"
dvs. totaler pr. metric:
SELECT * FROM crosstab( $$SELECT x.metrisk, t.country_code, x.val FROM ( TABLE tbl1 UNION ALL SELECT 'zzz_total', sum(metric1)::int, sum(metric2) )::int, sum(metrisk3)::int -- osv. FRA tbl1 ) t , LATERAL (VÆRDIER ('metric1', metric1) , ('metric2', metric2) , ('metric3', metric3) ) x(metrisk, val) ORDER BY 1, 2 DESC$$ )AS ct (metrisk tekst, i alt int, us int, uk int, fr int);
'zzz_total'
er en vilkårlig etiket, der skal sorteres sidste alfabetisk (eller du skal bruge 2-parameter formen crosstab()
).
Hvis du har masser af metric-kolonner, vil du måske bygge forespørgselsstrengen dynamisk. Relateret:
- Hvordan udfører man den samme aggregering på hver kolonne uden at angive kolonnerne?
- Eksekvering af forespørgsler dynamisk i PL/ pgSQL
Bemærk også, at den kommende Postgres 9.5 (i øjeblikket beta) introducerer en dedikeret SQL-sætning for ROLLUP
.
Relateret: