SELECCIONE columnas dinámicas sin funciones en PostgreSQL

Necesito seleccionar filas de dos y más tablas ("A", "B"). Tienen columnas de diferencias y yo no uso la inheritance para eso.

Asi que. Por ejemplo:

SELECT * FROM "A" UNION SELECT * FROM "B" 
 ERROR: each UNION query must have the same number of columns 

Puedo entender por qué.

Intento get columnas intersecadas del esquema raíz en la tabla raíz:

 SELECT column_name FROM information_schema.columns WHERE table_schema = 'client_root' AND table_name ='conditions' 

¡Está bien! Pero no uso la consulta:

 SELECT (SELECT column_name FROM information_schema.columns WHERE table_schema = 'client_root' AND table_name ='conditions') FROM "client_123"."A" 

Asi que. ¿Cómo puedo poner datos de sub selección en la selección de raíz?

Lo que estás tratando de hacer es casi imposible en su totalidad.

Crear SQL dynamic

Primero, esto es lo que puede hacer: una function plpgsql que crea el SQL para dicha consulta:

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

Llamada:

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

Te da la consulta completa. Ejecútalo en una segunda llamada.

Puede encontrar la mayoría de todo lo que utilicé aquí en el manual sobre las funciones de plpgsql .
La function agregada string_agg() se introdujo con PostgreSQL 9.0. En versiones anteriores, usted: array_to_string(array_agg(attname), ', ') .


Ejecutar SQL dynamic?

A continuación, esto es lo que apenas puedes hacer:

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

Una llamada de function requiere que especifique la list de columnas de destino. así que esto no es útil en absoluto:

 SELECT * from f_union_common_col('myschema1.tbl1', 'myschema2.tbl2') ERROR: a column definition list is requinetworking for functions returning "record" 

No hay una manera fácil de evitar esto. Tendría que crear dinámicamente una function o al less un tipo complejo. Aquí es donde me detengo.