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

CHỌN cột động không có hàm trong PostgreSQL

Những gì bạn đang cố gắng làm khó có thể thực hiện được toàn bộ.

Tạo SQL động

Đầu tiên, đây là những gì bạn có thể do:một hàm plpgsql tạo SQL cho một truy vấn như vậy:

CREATE OR REPLACE FUNCTION f_union_common_col_sql(text, text)
 RETURNS text
AS $function$
DECLARE 
  _cols text;
BEGIN

_cols := string_agg(attname, ', ')
FROM (
    SELECT a.attname
    FROM   pg_attribute a
    WHERE  a.attrelid = $1::regclass::oid
    AND    a.attnum >= 1
    INTERSECT
    SELECT a.attname
    FROM   pg_attribute a
    WHERE  a.attrelid = $2::regclass::oid
    AND    a.attnum >= 1
    ) x;

RETURN 'SELECT ' || _cols || '
FROM   ' || quote_ident($1) || '
UNION
SELECT ' || _cols || '
FROM   ' || quote_ident($1);

END;
$function$  LANGUAGE plpgsql;

COMMENT ON FUNCTION f_union_common_col_sql(text, text) IS 'Create SQL to query all visible columns that two tables have in common.
# Without duplicates. Use UNION ALL if you want to include duplicates.
# Depends on visibility dicatated by search_path
$1 .. table1: optionally schema-qualified, case sensitive!
$2 .. table2: optionally schema-qualified, case sensitive!';

Gọi:

SELECT f_union_common_col_sql('myschema1.tbl1', 'myschema2.tbl2');

Cung cấp cho bạn truy vấn hoàn chỉnh. Thực thi nó trong cuộc gọi thứ hai.

Bạn có thể tìm thấy hầu hết mọi thứ tôi đã sử dụng ở đây trong hướng dẫn sử dụng các hàm plpgsql .
hàm tổng hợp string_agg() đã được giới thiệu với PostgreSQL 9.0. Trong các phiên bản cũ hơn, bạn sẽ:array_to_string(array_agg(attname), ', ') .

Thực thi SQL động?

Tiếp theo, đây là những gì bạn khó có thể làm:

CREATE OR REPLACE FUNCTION f_union_common_col(text, text)
  RETURNS SETOF record AS
$BODY$
DECLARE 
  _cols text;
BEGIN

_cols := string_agg(attname, ', ')
FROM (
    SELECT a.attname
    FROM   pg_attribute a
    WHERE  a.attrelid = $1::regclass::oid
    AND    a.attnum >= 1
    INTERSECT
    SELECT a.attname
    FROM   pg_attribute a
    WHERE  a.attrelid = $2::regclass::oid
    AND    a.attnum >= 1
    ) x;

RETURN QUERY EXECUTE '
SELECT ' || _cols || '
FROM quote_ident($1)
UNION
SELECT ' || _cols || '
FROM quote_ident($2)';

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

COMMENT ON FUNCTION f_union_common_col(text, text) IS 'Query all visible columns that two tables have in common.
# Without duplicates. Use UNION ALL if you want to include duplicates.
# Depends on visibility dicatated by search_path
# !BUT! you need to specify a column definition list for every call. So, hardly useful.
$1 .. table1 (optionally schema-qualified)
$2 .. table1 (optionally schema-qualified)';

Một lệnh gọi hàm yêu cầu bạn chỉ định danh sách các cột mục tiêu. vì vậy điều này hầu như không hữu ích chút nào:

SELECT * from f_union_common_col('myschema1.tbl1', 'myschema2.tbl2')

ERROR:  a column definition list is required for functions returning "record"

Không có cách nào dễ dàng để giải quyết vấn đề này. Bạn sẽ phải tạo động một hàm hoặc ít nhất là một kiểu phức tạp. Đây là nơi tôi dừng lạ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. Lịch sử triển khai của bảng PostgreSQL

  2. sự khác biệt đối chiếu postgres. osx v ubuntu

  3. ngủ đông - Postgres- danh sách mục tiêu có thể có nhiều nhất 1664 mục nhập

  4. lỗi cú pháp tại hoặc gần 'order' trong PostgreSQL

  5. Postgres:Tại sao hiệu suất quá tệ trên các lựa chọn con có Offset / Limit