PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Завъртане на множество колони с помощта на Tablefunc

Проблемът с вашата заявка е, че 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<>цигулка тук - с по-проста настройка на теста и по-малко редове.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Двойка ключови стойности в PostgreSQL

  2. Колоната за промяна на миграцията на Rails за използване на Postgres масиви

  3. Как да актуализирате множество колони в PostgreSQL

  4. Как да изберете идентификатор с група за максимална дата по категория в PostgreSQL?

  5. PostgreSQL изтрива цялото съдържание