sql >> Databáze >  >> RDS >> PostgreSQL

Pivot na více sloupců pomocí Tablefunc

Problém s vaším dotazem je, že b a c sdílet stejné časové razítko 2012-01-02 00:00:00 a máte timestamp sloupec timeof první ve svém dotazu, takže – i když jste přidali tučné zvýraznění – b a c jsou pouze další sloupce, které spadají do stejné skupiny 2012-01-02 00:00:00 . Pouze první (b ) je vráceno od (s citací návodu):

row_name sloupec musí být první. category a value sloupce musí být poslední dva sloupce v tomto pořadí. Jakékoli sloupce mezi row_name a category jsou považovány za „extra“. Sloupce "navíc" očekáváme, že budou stejné pro všechny řádky se stejným row_name hodnotu.

Tučné zdůraznění min.
Stačí změnit pořadí prvních dvou sloupců a vytvořit entity název řádku a funguje podle potřeby:

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 musí být samozřejmě jedinečné.

Opakujte

  • row_name první
  • (volitelné) extra sloupce další
  • category (jak je definováno druhým parametrem) a value poslední .

Další sloupce se vyplňují od prvního řádek z každého row_name rozdělit. Hodnoty z jiných řádků jsou ignorovány, každý row_name má pouze jeden sloupec vyplnit. Obvykle by byly stejné pro každý řádek jednoho row_name , ale to je na vás.

Pro různé nastavení ve vaší odpovědi:

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

Není divu, že dotazy ve vašem testu fungují strašně. Vaše testovací nastavení má 14 milionů řádků a vy zpracujete všechny z nich, než většinu vyhodíte s LIMIT 1000 . Chcete-li snížit sadu výsledků, přidejte do zdrojového dotazu podmínky WHERE nebo LIMIT!

Navíc pole, se kterým pracujete, je zbytečně drahé. Místo toho generuji náhradní název řádku pomocí dense_rank().

db<>housle zde – s jednodušším testovacím nastavením a menším počtem řádků.



  1. EXTRACT (datetime) Funkce v Oracle

  2. Převeďte časové razítko Unixu na člověkem čitelné datum pomocí MySQL

  3. Co je databáze, proč databáze?

  4. DATETIMEOFFSETFROMPARTS() Příklady v SQL Server (T-SQL)