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

Ruota su più colonne usando Tablefunc

Il problema con la tua query è che b e c condividi lo stesso timestamp 2012-01-02 00:00:00 e hai il timestamp colonna timeof prima nella tua query, quindi, anche se hai aggiunto l'enfasi in grassetto, b e c sono solo colonne extra che rientrano nello stesso gruppo 2012-01-02 00:00:00 . Solo il primo (b ) viene restituito poiché (citando il manuale):

Il row_name la colonna deve essere la prima. La category e value le colonne devono essere le ultime due colonne, in quest'ordine. Qualsiasi colonna tra row_name e category sono trattati come "extra". Le colonne "extra" prevedono che siano le stesse per tutte le righe con lo stesso row_name valore.

Il grassetto è mio.
Ripristina l'ordine delle prime due colonne per creare entity il nome della riga e funziona come desiderato:

SELECT * FROM crosstab(
      'SELECT entity, timeof, status, ct
       FROM   t4
       ORDER  BY 1'
      ,'VALUES (1), (0)')
 AS ct (
    "Attribute" character
   ,"Section" timestamp
   ,"status_1" int
   ,"status_0" int);

entity deve essere unico, ovviamente.

Ripeti

  • row_name prima
  • (opzionale) extra colonne successivo
  • category (come definito dal secondo parametro) e value ultimo .

Le colonne extra vengono riempite dalla prima riga da ogni row_name partizione. I valori delle altre righe vengono ignorati, c'è solo una colonna per row_name riempire. In genere sarebbero gli stessi per ogni riga di un row_name , ma dipende da te.

Per la diversa configurazione nella tua risposta:

SELECT localt, entity
     , msrmnt01, msrmnt02, msrmnt03, msrmnt04, msrmnt05  -- , more?
FROM   crosstab(
        'SELECT dense_rank() OVER (ORDER BY localt, entity)::int AS row_name
              , localt, entity -- additional columns
              , msrmnt, val
         FROM   test
         -- WHERE  ???   -- instead of LIMIT at the end
         ORDER  BY localt, entity, msrmnt
         -- LIMIT ???'   -- instead of LIMIT at the end
     , $$SELECT generate_series(1,5)$$)  -- more?
     AS ct (row_name int, localt timestamp, entity int
          , msrmnt01 float8, msrmnt02 float8, msrmnt03 float8, msrmnt04 float8, msrmnt05 float8 -- , more?
            )
LIMIT 1000  -- ??!!

Non c'è da stupirsi che le query nel tuo test funzionino in modo terribile. La tua configurazione di prova ha 14 milioni di righe ed elabori tutte prima di buttarne via la maggior parte con LIMIT 1000 . Per un set di risultati ridotto, aggiungi le condizioni WHERE o un LIMIT alla query di origine!

Inoltre, l'array con cui lavori è inutilmente costoso. Genero invece un nome di riga surrogato con dense_rank().

db<>violino qui - con una configurazione di prova più semplice e meno righe.