Проблемът с вашата заявка е, че b и c споделяне на същото времеви печат 2012-01-02 00:00:00 , и имате timestamp колона timeof първо във вашата заявка, така че - въпреки че сте добавили удебелен акцент - b и c са само допълнителни колони, които попадат в една и съща група 2012-01-02 00:00:00 . Само първият (b ) се връща, тъй като (цитирайки ръководството):
row_nameколоната трябва да е първа.categoryиvalueколоните трябва да са последните две колони в този ред. Всички колони междуrow_nameиcategoryсе третират като "екстра". „Допълнителните“ колони сеочаква да бъдат еднакви за всички редове със същияrow_nameстойност.
Удебелен акцент мой.
Просто върнете реда на първите две колони, за да направите entity името на реда и то работи по желание:
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 трябва да бъде уникален, разбира се.
Повторете
row_nameпърво- (по избор)
extraколони следващи category(както е дефинирано от втория параметър) иvalueпоследно .
Допълнителните колони се попълват от първата ред от всеки row_name дял. Стойностите от други редове се игнорират, има само една колона за row_name да попълня. Обикновено те биха били еднакви за всеки ред от един row_name , но това зависи от вас.
За различната настройка във вашия отговор:
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 -- ??!!
Нищо чудно, че заявките във вашия тест се представят ужасно. Вашата тестова настройка има 14 милиона реда и обработвате всички от тях, преди да изхвърлите по-голямата част от тях с LIMIT 1000 . За намален набор от резултати добавете условия WHERE или LIMIT към изходната заявка!
Освен това масивът, с който работите, е ненужно скъп. Вместо това генерирам заместващо име на ред с dense_rank().
db<>цигулка тук - с по-проста настройка на теста и по-малко редове.