Das Problem mit Ihrer Abfrage ist, dass b
und c
denselben Zeitstempel haben 2012-01-02 00:00:00
, und Sie haben den timestamp
Spalte timeof
zuerst in Ihrer Abfrage, also - obwohl Sie fett hervorgehoben haben - b
und c
sind nur zusätzliche Spalten, die in dieselbe Gruppe 2012-01-02 00:00:00
fallen . Nur der erste (b
) wird zurückgegeben seit (unter Angabe des Handbuchs):
Der row_name
Spalte muss an erster Stelle stehen. Die category
und value
Spalten müssen die letzten beiden Spalten in dieser Reihenfolge sein. Alle Spalten zwischen row_name
und category
werden als „zusätzlich“ behandelt. Die "zusätzlichen" Spalten sind voraussichtlich gleich für alle Zeilen mit demselben row_name
Wert.
Fettdruck von mir.
Kehren Sie einfach die Reihenfolge der ersten beiden Spalten um, um entity
zu erstellen den Zeilennamen und es funktioniert wie gewünscht:
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
muss natürlich eindeutig sein.
Wiederholen
row_name
zuerst- (optional)
extra
Spalten weiter category
(wie durch den zweiten Parameter definiert) undvalue
zuletzt .
Zusätzliche Spalten werden von der ersten an gefüllt Zeile aus jedem row_name
Partition. Werte aus anderen Zeilen werden ignoriert, es gibt nur eine Spalte pro row_name
füllen. Normalerweise wären diese für jede Zeile eines row_name
gleich , aber das liegt an Ihnen.
Für die unterschiedliche Einrichtung in Ihrer Antwort:
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 -- ??!!
Kein Wunder, dass die Abfragen in Ihrem Test schrecklich abschneiden. Ihr Testaufbau hat 14 Millionen Zeilen und Sie verarbeiten alle von ihnen, bevor Sie das meiste davon mit LIMIT 1000
wegwerfen . Für eine reduzierte Ergebnismenge fügen Sie WHERE-Bedingungen oder ein LIMIT zur Quellabfrage hinzu!
Außerdem ist das Array, mit dem Sie arbeiten, unnötig teuer. Ich generiere stattdessen einen Ersatzzeilennamen mit dense_rank().
db<>fiddle hier - mit einem einfacheren Testaufbau und weniger Zeilen.