sql >> Database teknologi >  >> RDS >> PostgreSQL

Krydstabuleringstransponeringsanmodning

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:

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:

Bemærk også, at den kommende Postgres 9.5 (i øjeblikket beta) introducerer en dedikeret SQL-sætning for ROLLUP .
Relateret:




  1. Oprettelse af et link fra Google Charts tidslinjeelement

  2. Ansible idempotent MySQL installation Playbook

  3. Optimer forespørgsel (indeksering, FORKLAR) Mysql

  4. Erstat nulls-værdier i sql ved hjælp af select-sætning i mysql?