PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

ИЗБЕРЕТЕ динамични колони без функции в PostgreSQL

Това, което се опитвате да направите, едва ли е възможно в своята цялост.

Създайте динамичен SQL

Първо, ето какво можете do:plpgsql функция, която създава SQL за такава заявка:

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!';

Обаждане:

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

Дава ви пълната заявка. Изпълнете го при второ повикване.

Можете да намерите почти всичко, което използвах тук, в ръководството за функциите на plpgsql .
обобщаваща функция string_agg() беше въведен с PostgreSQL 9.0. В по-стари версии бихте:array_to_string(array_agg(attname), ', ') .

Да се ​​изпълни ли динамичен SQL?

След това, ето какво едва ли можете направи:

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)';

Извикването на функция изисква да посочите списъка с целеви колони. така че това едва ли е полезно:

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

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

Няма лесен начин за това. Ще трябва да създадете динамично функция или поне сложен тип. Тук спирам.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изравняване на релация с масив за излъчване на един ред на запис в масив

  2. Вземете първата дата от месеца в postgres

  3. Как мога да свържа електронна таблица на Google с PostgreSQL?

  4. Как да се свържа с PostgreSQL, без да посоча име на база данни?

  5. Как да свържа всички резултати от реда на таблицата?