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
.