PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Przestaw na wiele kolumn za pomocą funkcji Tablefunc

Problem z zapytaniem polega na tym, że b i c udostępnij ten sam znacznik czasu 2012-01-02 00:00:00 i masz timestamp kolumna timeof najpierw w zapytaniu, więc - mimo dodania pogrubionego podkreślenia - b i c to tylko dodatkowe kolumny należące do tej samej grupy 2012-01-02 00:00:00 . Tylko pierwszy (b ) jest zwracane, ponieważ (powołując się na instrukcję):

row_name kolumna musi być pierwsza. category i value kolumny muszą być dwiema ostatnimi kolumnami w tej kolejności. Dowolne kolumny między row_name i category traktowane są jako „dodatkowe”. „Dodatkowe” kolumny oczekuje się, że będą takie same dla wszystkich wierszy o tej samej row_name wartość.

Pogrubiony nacisk na kopalnię.
Po prostu odwróć kolejność pierwszych dwóch kolumn, aby utworzyć entity nazwę wiersza i działa zgodnie z potrzebami:

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 musi być oczywiście wyjątkowy.

Powtórz

  • row_name pierwszy
  • (opcjonalnie) extra kolumny następne
  • category (zgodnie z drugim parametrem) i value ostatni .

Dodatkowe kolumny są wypełniane od pierwszego wiersz z każdego row_name przegroda. Wartości z innych wierszy są ignorowane, jest tylko jedna kolumna na row_name wypełnić. Zazwyczaj byłyby to takie same dla każdego wiersza jednego row_name , ale to zależy od Ciebie.

Dla innej konfiguracji w Twojej odpowiedzi:

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  -- ??!!

Nic dziwnego, że zapytania w twoim teście działają fatalnie. Twoja konfiguracja testowa ma 14 mln wierszy i przetwarzasz wszystkie z nich przed wyrzuceniem większości z LIMIT 1000 . Aby uzyskać ograniczony zestaw wyników, dodaj warunki WHERE lub LIMIT do zapytania źródłowego!

Ponadto macierz, z którą pracujesz, jest niepotrzebnie droga. Zamiast tego generuję zastępczą nazwę wiersza za pomocą gęstości_rank().

db<>skrzypce tutaj - z prostszą konfiguracją testową i mniejszą liczbą wierszy.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zmienić własność wszystkich obiektów w określonym schemacie w PostgreSQL?

  2. Konfiguracja PostgreSQL w celu zapewnienia ciągłości działania

  3. Migracja z Oracle do PostgreSQL — co powinieneś wiedzieć

  4. Jak używać pgBackRest do tworzenia kopii zapasowych PostgreSQL i TimescaleDB?

  5. Jak zainstalować wiele serwerów PostgreSQL w systemie RedHat Linux?