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

Pilih satu set kolom dinamis dari tabel dan dapatkan jumlah untuk masing-masing

Kueri ini membuat pernyataan DML lengkap yang Anda cari:

WITH x AS (
   SELECT 'public'::text     AS _schema  -- provide schema name ..
         ,'somereport'::text AS _tbl     -- .. and table name once
   )
SELECT 'SELECT ' || string_agg('sum(' || quote_ident(column_name)
                 || ') AS sum_' || quote_ident(column_name), ', ')
       || E'\nFROM   ' || quote_ident(x._schema) || '.' || quote_ident(x._tbl)
FROM   x, information_schema.columns
WHERE  table_schema = _schema
AND    table_name = _tbl
AND    data_type = 'integer'
GROUP  BY x._schema, x._tbl;

Anda dapat menjalankannya secara terpisah atau membungkus kueri ini dalam fungsi plpgsql dan menjalankan kueri secara otomatis dengan EXECUTE :

Otomasi penuh

Diuji dengan PostgreSQL 9.1.4

CREATE OR REPLACE FUNCTION f_get_sums(_schema text, _tbl text)
  RETURNS TABLE(names text[], sums bigint[]) AS
$BODY$
BEGIN

RETURN QUERY EXECUTE (
    SELECT 'SELECT ''{'
           || string_agg(quote_ident(c.column_name), ', ' ORDER BY c.column_name)
           || '}''::text[],
           ARRAY['
           || string_agg('sum(' || quote_ident(c.column_name) || ')'
                                                   , ', ' ORDER BY c.column_name)
           || ']
    FROM   '
           || quote_ident(_schema) || '.' || quote_ident(_tbl)
    FROM   information_schema.columns c
    WHERE  table_schema = _schema
    AND    table_name = _tbl
    AND    data_type = 'integer'
    );

END;
$BODY$
  LANGUAGE plpgsql;

Telepon:

SELECT unnest(names) AS name, unnest (sums) AS col_sum
FROM   f_get_sums('public', 'somereport');

Pengembalian:

   name        | col_sum
---------------+---------
 int_col1      |    6614
 other_int_col |    8364
 third_int_col | 2720642

Jelaskan

Kesulitannya adalah mendefinisikan RETURN ketik untuk fungsi tersebut, sementara jumlah dan nama kolom yang dikembalikan akan bervariasi. Satu detail yang sedikit membantu:Anda hanya ingin integer kolom.

Saya memecahkan ini dengan membentuk array bigint (sum(int_col) mengembalikan bigint ). Selain itu saya mengembalikan array nama kolom. Keduanya diurutkan berdasarkan abjad berdasarkan nama kolom.

Dalam panggilan fungsi saya membagi array ini dengan unnest() tiba di format tampan yang ditampilkan.

Kueri yang dibuat dan dijalankan secara dinamis adalah hal yang canggih. Jangan bingung dengan beberapa lapisan kutipan. Pada dasarnya Anda memiliki EXECUTE yang membutuhkan argumen teks yang berisi kueri SQL untuk dieksekusi. Teks ini, pada gilirannya, disediakan oleh kueri SQL sekunder yang membangun string kueri dari kueri utama.

Jika ini terlalu banyak sekaligus atau plpgsql agak baru untuk Anda, mulailah dengan jawaban terkait ini di mana saya menjelaskan dasar-dasar yang berhubungan dengan fungsi yang lebih sederhana dan menyediakan tautan ke manual untuk fitur-fitur utama.

Jika kinerja adalah permintaan penting katalog Postgres secara langsung (pg_catalog.pg_attributes ) daripada menggunakan information_schema.columns standar (tapi lambat) . Berikut adalah contoh sederhana dengan pg_attributes .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara melakukan upser dengan benar di postgres 9.5

  2. Apa cara terbaik untuk memuat sejumlah besar data ke dalam PostgreSQL?

  3. Memberi tahu perubahan postgres ke aplikasi Java

  4. Paket 'pgadmin4' tidak memiliki kandidat instalasi, untuk Ubuntu 20.04

  5. Masalah dengan wadah buruh pelabuhan postgresql dan pgadmin