sql >> Database teknologi >  >> RDS >> PostgreSQL

Pivot på flere kolonner ved hjælp af Tablefunc

Problemet med din forespørgsel er, at b og c del det samme tidsstempel 2012-01-02 00:00:00 , og du har timestamp kolonne timeof først i din forespørgsel, så - selvom du tilføjede fed fremhævelse - b og c er blot ekstra kolonner, der falder i samme gruppe 2012-01-02 00:00:00 . Kun den første (b ) returneres siden (med henvisning til manualen):

row_name kolonne skal være først. category og value kolonner skal være de sidste to kolonner i nævnte rækkefølge. Alle kolonner mellem row_name og category behandles som "ekstra". De "ekstra" kolonner forventes at være de samme for alle rækker med det samme row_name værdi.

Fed fremhævelse min.
Bare vend rækkefølgen af ​​de første to kolonner for at lave entity rækkenavnet og det virker som ønsket:

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 skal selvfølgelig være unikt.

Gentag

  • row_name først
  • (valgfrit) extra kolonner næste
  • category (som defineret af den anden parameter) og value sidste .

Ekstra kolonner udfyldes fra den første række fra hver row_name skillevæg. Værdier fra andre rækker ignoreres, der er kun én kolonne pr. row_name at fylde. Typisk vil disse være de samme for hver række af én row_name , men det er op til dig.

For de forskellige opsætninger i dit svar:

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

Ikke underligt, at forespørgslerne i din test fungerer forfærdeligt. Din testopsætning har 14 mio. rækker, og du behandler alle af dem, før du smider det meste væk med LIMIT 1000 . For et reduceret resultatsæt skal du tilføje WHERE-betingelser eller en LIMIT til kildeforespørgslen!

Derudover er det array, du arbejder med, unødvendigt dyrt. Jeg genererer et surrogatrækkenavn med dense_rank() i stedet.

db<>violin her - med en enklere testopsætning og færre rækker.



  1. Anbefalede Intel-processorer til SQL Server 2014 – marts 2015

  2. Hvordan kan jeg udstede en enkelt kommando fra kommandolinjen gennem sql plus?

  3. Sammenligning af store og små bogstaver i SQL

  4. Forskellen mellem #temptable og ##Temptable?