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

Pilih sel baris sebagai kolom baru

Pertanyaan ini jauh lebih sulit untuk memecahkan dari yang mungkin Anda harapkan. Upaya Anda dengan crosstab() sedang membidik ke arah yang benar. Tetapi untuk menetapkan nama kolom dinamis, Anda memerlukan SQL dinamis sebagai tambahan:EXECUTE dalam fungsi plpgsql.

Ubah tipe data kolom infos.type dari text ke regtype untuk mencegah injeksi SQL dan kesalahan lainnya. Misalnya, Anda memiliki tipe data number , yang bukan tipe data PostgreSQL yang valid. Saya menggantinya dengan numeric , sehingga dapat bekerja.

Anda bisa sederhanakan tugas dengan menghindari nama kolom yang memerlukan tanda kutip ganda. Seperti nume_anterior bukannya "nume anterior" .

Anda mungkin ingin menambahkan kolom row_id ke tabel Anda info_data untuk menandai semua elemen dari satu baris. Anda membutuhkannya untuk crosstab() fungsi, dan memungkinkan Anda untuk mengabaikan kolom dengan NULL nilai-nilai. crosstab() fungsi dengan dua parameter dapat menangani kolom yang hilang. Saya mensintesis kolom yang hilang dengan ekspresi (d.id-1)/13 di bawah ini - yang berfungsi untuk data dalam contoh Anda.

Anda perlu menginstal tablefunc modul tambahan (sekali per basis data):

CREATE EXTENSION tablefunc;

Temukan penjelasan dan tautan tambahan dalam jawaban terkait ini .

Fungsi ini akan melakukan apa yang dicari:

CREATE OR REPLACE FUNCTION f_mytbl()
  RETURNS TABLE (id int
, nume text           , prenume text       , cnp numeric
, "nume anterior" text, "stare civila" text, cetatenie text
, rezidenta text      , adresa text        , "tip act" text
, "serie ci" text     , "numar ci" text    , "data eliberarii" text
, "eliberat de" text)
  LANGUAGE plpgsql AS
$BODY$
BEGIN

RETURN QUERY EXECUTE $f$
SELECT *
FROM   crosstab(
    'SELECT (d.id-1)/13 -- AS row_id
          , i.id, d.value
     FROM   infos i
     JOIN   info_data d ON d.id_info = i.id
     ORDER  BY 1, i.id',

    'SELECT id
     FROM   infos
     ORDER  BY id'
    )
AS tbl ($f$ || 'id int,
, nume text           , prenume text       , cnp numeric
, "nume anterior" text, "stare civila" text, cetatenie text
, rezidenta text      , adresa text        , "tip act" text
, "serie ci" text     , "numar ci" text    , "data eliberarii" text
, "eliberat de" text)';

END;
$BODY$;

Telepon:

SELECT * FROM x.mytbl();

Jangan bingung dengan penawaran dolar .

BTW:Saya membuat daftar kolom dengan pernyataan ini:

SELECT 'id int,' || string_agg(quote_ident(name) || ' ' || type
                              ,', ' ORDER BY i.id) 
FROM   infos i;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lakukan VACUUM FULL dengan JPA

  2. Bagaimana current_timestamp() Bekerja di PostgreSQL

  3. Bisakah saya mengembalikan transaksi yang sudah saya lakukan? (Data hilang)

  4. Agregat tidak diizinkan dalam klausa WHERE dalam kesalahan postgreSQL

  5. masalah menjalankan liquibase dengan maven dan postgres-db