PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Chọn một tập hợp các cột động từ một bảng và lấy tổng cho mỗi cột

Truy vấn này tạo ra câu lệnh DML hoàn chỉnh mà bạn đang theo đuổi:

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;

Bạn có thể thực thi nó một cách riêng biệt hoặc gói truy vấn này trong một hàm plpgsql và chạy truy vấn tự động với EXECUTE :

Tự động hóa hoàn toàn

Đã kiểm tra với 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;

Gọi:

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

Lợi nhuận:

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

Giải thích

Khó khăn là xác định RETURN nhập cho hàm, trong khi số và tên của các cột được trả về sẽ khác nhau. Một chi tiết giúp ích một chút:bạn chỉ muốn integer cột.

Tôi đã giải quyết vấn đề này bằng cách tạo một mảng bigint (sum(int_col) trả về bigint ). Ngoài ra, tôi trả về một mảng tên cột. Cả hai đều được sắp xếp theo thứ tự bảng chữ cái theo tên cột.

Trong lệnh gọi hàm, tôi tách các mảng này bằng unnest() đến định dạng đẹp được hiển thị.

Truy vấn được tạo và thực thi động là công cụ nâng cao. Đừng nhầm lẫn bởi nhiều lớp dấu ngoặc kép. Về cơ bản, bạn có EXECUTE nhận một đối số văn bản có chứa truy vấn SQL để thực thi. Đến lượt nó, văn bản này được cung cấp bởi truy vấn SQL thứ cấp xây dựng chuỗi truy vấn của truy vấn chính.

Nếu quá nhiều cùng một lúc hoặc plpgsql khá mới đối với bạn, hãy bắt đầu với câu trả lời có liên quan này nơi tôi giải thích những điều cơ bản về một chức năng đơn giản hơn nhiều và cung cấp các liên kết đến sách hướng dẫn cho các tính năng chính.

Nếu hiệu suất là truy vấn cần thiết cho danh mục Postgres trực tiếp (pg_catalog.pg_attributes ) thay vì sử dụng information_schema.columns . Đây là một ví dụ đơn giản với 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. Không tìm thấy lớp đang tải JDBC org.postgresql.Driver

  2. K-Nearest Neighbor Query trong PostGIS

  3. dữ liệu bổ sung sau cột dự kiến ​​cuối cùng trong khi cố gắng nhập tệp csv vào postgresql

  4. PGError:không có kết nối với máy chủ sau khi không hoạt động

  5. Sử dụng Docker để khởi chạy ứng dụng web, không thể kết nối với Postgresql DB?