スキーマ内のすべてのテーブルから選択することは可能ですか?すべてのテーブル名を
select table_name from information_schema.tables
しかし、それを使用してクエリを実行することはできません。
テーブル名がわからない場合(つまり、いくつかの変数またはサブクエリから)、「通常の」クエリを記述できないため、直接実行することはできません。ただし、このために動的SQLステートメントを作成して実行できます。たとえば、すべてのテーブルの列 'name'が必要な場合は、次のようにすることができます( PL/pgSQL関数 内で)。
_FOR i IN SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'your_desired_schema'
LOOP
sql_string := sql_string || format($$
-- some whitespace is mandatory here
UNION
SELECT name FROM %I
$$,
i.table_name);
END LOOP;
EXECUTE sql_string;
_
ただし、この形式では機能しません。変数に入力しない限り、SELECT
でplpqsql
を実行できないためです。このための一時テーブルを作成するか、(他のFOR
ループで)結果をループするか、またはUNION
を使用せずに、必要に応じてすべての反復で単に戻ります。
そしてもちろん、これはすべてのテーブルから単一の列(または複数の、ただし常に同じ名前とタイプを持つ)を選択することを前提としています。すべてのテーブルのすべてのデータが必要な場合、テーブルは同じ構造(同じ列型、同じ順序、同じ名前)でなければなりません。
ノート:
format()
関数はバージョン9.1で導入されましたDO
ブロックの使用について言及していました。 別の答え で指摘されているように、行の戻り値としてSELECT
を単純に使用することはできないという問題があります。OK、本当に遅いですが、同じ問題を解決するために解決し、FUNCTION
が機能しなかったため、DO
を使用して特定のスキーマの下のすべてのテーブルのすべての行を返すことができました。 DO
を使用しても何も返されなかったので、ここに私のFUNCTION
を示します。
CREATE OR REPLACE FUNCTION union_all_tables()
RETURNS TABLE
(
id integer,
full_name varchar(100),
col3 varchar(200),
col4 numeric,
col5 char,
version bigint
) AS
$$
DECLARE
dynamic_query text = '';
r_row record;
BEGIN
FOR r_row IN SELECT table_schema || '.' || table_name qualified_table_name
FROM information_schema.tables
WHERE table_schema = 'staging'
AND table_name LIKE '%_postfix'
LOOP
dynamic_query := dynamic_query || format('UNION SELECT ' ||
'id, ' ||
'full_name, ' ||
'col3, ' ||
'col4, ' ||
'col5, ' ||
'version ' ||
'FROM %s ', r_row.qualified_table_name) || E'\n'; -- adding new line for pretty print, it is not necessary
END LOOP;
-- before we execute the query, we need to remove first "UNION " from the string
dynamic_query := SUBSTRING(dynamic_query, 7) || ';';
-- printing the statement as a notice so you know that the statement is in a good format,
-- or you can copy paste it and try it in the console to know if that statement is working or not.
RAISE NOTICE 'Union all tables in staging, executing statement: %', dynamic_query;
RETURN QUERY EXECUTE dynamic_query;
END;
$$
LANGUAGE plpgsql;
AND table_name LIKE '%_postfix'
をここに追加したのは、命名規則があり、そのための頭痛を軽減したい場合は、ここに追加します。不要な場合は削除します。また、UNION
を作成する場合は、すべてのテーブルをフォローする必要があります。同じ構造、必要な共通の列を選択しない場合(これは私のソリューションではこれが私のケースです)、それ以外の場合、すべての列が必要な場合は、さらに複雑なスクリプトが必要です。
このソリューションは、PostgreSQL 10および11で私に役立ちます。
これは、上記のアプローチに基づく回避策です。
DECLARE
tables CURSOR FOR SELECT *
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY "table_name" ASC
LIMIT ((SELECT count(*)
FROM information_schema.tables
WHERE table_schema = 'public')-1);
--Because the following prepared string starts with a 'UNION ALL',
--this completes the query string with a select starting with the last table
sql_string text := 'SELECT field1, field7, field8, "source" FROM ' || quote_IDENT((SELECT "table_name" FROM information_schema.tables WHERE table_schema = 'public' ORDER BY "table_name" DESC LIMIT 1));
BEGIN
FOR table_record IN tables LOOP
sql_string := sql_string || '
UNION ALL
SELECT columns FROM ' || quote_IDENT(table_record."table_name");
END LOOP;
sql_string := sql_string||';';
RETURN sql_string;
--EXECUTE sql_string;
END;