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) evalue
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.