PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Pivot pada Beberapa Kolom menggunakan Tablefunc

Masalah dengan kueri Anda adalah b dan c bagikan stempel waktu yang sama 2012-01-02 00:00:00 , dan Anda memiliki timestamp kolom timeof pertama dalam kueri Anda, jadi - meskipun Anda menambahkan penekanan tebal - b dan c hanyalah kolom tambahan yang termasuk dalam grup yang sama 2012-01-02 00:00:00 . Hanya yang pertama (b ) dikembalikan sejak (mengutip manual):

row_name kolom harus terlebih dahulu. category dan value kolom harus dua kolom terakhir, dalam urutan itu. Setiap kolom di antara row_name dan category diperlakukan sebagai "tambahan". Kolom "ekstra" diharapkan sama untuk semua baris dengan row_name yang sama nilai.

Penekanan tebal milik saya.
Kembalikan saja urutan dua kolom pertama untuk membuat entity nama baris dan berfungsi seperti yang diinginkan:

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 harus unik, tentu saja.

Ulangi

  • row_name pertama
  • (opsional) extra kolom berikutnya
  • category (sebagaimana didefinisikan oleh parameter kedua) dan value terakhir .

Kolom tambahan diisi dari pertama baris dari setiap row_name partisi. Nilai dari baris lain diabaikan, hanya ada satu kolom per row_name untuk mengisi. Biasanya itu akan sama untuk setiap baris dari satu row_name , tapi itu terserah Anda.

Untuk pengaturan yang berbeda dalam jawaban Anda:

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

Tidak heran kueri dalam pengujian Anda berkinerja buruk. Penyiapan pengujian Anda memiliki 14 juta baris dan Anda memproses semua dari mereka sebelum membuang sebagian besar dengan LIMIT 1000 . Untuk kumpulan hasil yang dikurangi, tambahkan kondisi WHERE atau LIMIT ke kueri sumber!

Plus, array yang Anda gunakan tidak perlu mahal di atasnya. Saya membuat nama baris pengganti dengan density_rank() sebagai gantinya.

db<>biola di sini - dengan penyiapan pengujian yang lebih sederhana dan baris yang lebih sedikit.



  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 9.1:Cara menggabungkan baris dalam array tanpa duplikat, GABUNG tabel lain

  2. Objek Besar tidak dapat digunakan dalam mode komit otomatis

  3. Pernyataan yang Disiapkan tentang Postgresql di Rails

  4. Bagaimana memaksa evaluasi subquery sebelum bergabung / menekan ke server asing

  5. Jelaskan JOIN vs. LEFT JOIN dan WHERE kondisi saran kinerja secara lebih rinci