6
votes

Pivot PostgreSQL? Croststab?

J'ai une table (qui résulte d'une requête) à Postgres qui comporte un ensemble de lignes (résultat d'une somme compliquée de données) qui ressemble à ce qui suit: (Les noms de colonne sont les noms de chaque jour et la valeur de chaque colonne est une double précision.)

Sun lundi Mer jeudi Jeudi Fri

1.24 1.11 4.51 3.21 2.21 1.01

Je dois avoir les données sélectionnées d'une ligne afin que les résultats ressemblent au ci-dessous:

Montant du jour
Soleil 1.24
Lun 1.11
Mardi 4.51
Mer 3.21
Jeudi 2.21
Ven 1.01

J'ai des difficultés à commencer, car j'ai vraiment besoin de changer les noms de colonne en valeurs et pivoter le résultat. J'ai essayé d'expérimenter le crosstab mais je ne suis pas tout à fait sûr que c'est ce dont j'ai besoin. Tout conseil ou suggestions qui pourraient me faire aller dans la bonne direction seraient très appréciés.


3 commentaires

La question connexe est Stackoverflow.com/questions/1128737/unpivot-and-postgresql


Avec "Expérimentation avec Crosstab" Vous vous référez au module Croststab Contrib?


Oui, je regardais la fonction de tablefunc.croststab - Postgresql.org/docs/Current /Static/tablefunc.html


3 Réponses :


0
votes

Je ne connais pas la mise en œuvre directe, mais peut-être quelque chose comme http://www.mail-archive.com/dhis2-users@lists.launchpad.net/msg00109.html pourrait vous aider à démarrer

Bien sûr, si vous n'avez pas besoin d'une solution flexible que vous n'avez pas besoin peut faire xxx

(samedi?)


0 commentaires

1
votes

Objets de test:

create or replace function unpivot(t) returns setof record 
                           language plpgsql immutable strict as $$
declare
  q record;
  r record;
begin
  for q in ( select attname, attnum 
             from pg_attribute 
             where attnum>0 and attrelid = ( select oid 
                                             from pg_class 
                                             where relname = 't' ) ) loop 
    for r in execute 'select '''||q.attname||'''::text, '||
                             '('||$1::text||'::t).'||q.attname||'::numeric' loop
      return next r;
    end loop;
  end loop;
  return;
end;$$;

select *
from unpivot((select row(t.*)::t from t)) 
       as foo(day text, amount numeric);


0 commentaires

3
votes

Modification de la première réponse de @jack Douglas: xxx

Un peu moins coûteux selon le planificateur de requête 9.0:

SEQ Numérisation sur T (Coût = 0,00 ..11.62 lignes = 360 largeur = 192)

contre

SCAN SUBQUERY sur z (coût = 0,00..12,16 lignes = 360 largeur = 68) -> SEQ Scan on t (coût = 0,00..11,26 lignes = 360 largeur = 192)


0 commentaires