El problema con tu consulta es que b
y c
compartir la misma marca de tiempo 2012-01-02 00:00:00
, y tienes la timestamp
columna timeof
primero en su consulta, por lo que, aunque haya agregado énfasis en negrita, b
y c
son solo columnas adicionales que caen en el mismo grupo 2012-01-02 00:00:00
. Solo el primero (b
) se devuelve desde (citando el manual):
El row_name
la columna debe ser la primera. La category
y value
las columnas deben ser las dos últimas columnas, en ese orden. Cualquier columna entre row_name
y category
se tratan como "extra". Se espera que las columnas "extra" sean las mismas para todas las filas con el mismo row_name
valor.
El énfasis en negrita es mío.
Simplemente invierta el orden de las dos primeras columnas para hacer entity
el nombre de la fila y funciona como se desea:
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
debe ser único, por supuesto.
Reiterar
row_name
primero- (opcional)
extra
columnas siguiente category
(según lo definido por el segundo parámetro) yvalue
último .
Las columnas adicionales se rellenan desde el primero fila de cada row_name
dividir. Los valores de otras filas se ignoran, solo hay una columna por row_name
llenar. Por lo general, serían los mismos para cada fila de un row_name
, pero eso depende de ti.
Para la configuración diferente en su respuesta:
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 -- ??!!
No es de extrañar que las consultas en su prueba funcionen terriblemente. Su configuración de prueba tiene 14 millones de filas y usted procesa todas de ellos antes de tirar la mayor parte con LIMIT 1000
. Para obtener un conjunto de resultados reducido, agregue condiciones DONDE o un LÍMITE a la consulta de origen.
Además, la matriz con la que trabaja es innecesariamente costosa. Genero un nombre de fila sustituto con dense_rank() en su lugar.
db<>violín aquí, con una configuración de prueba más simple y menos filas.