いずれにせよ、動的SQLが必要です。
指定されたパラメータとしてのテーブル名
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS -- adapt to actual data types!
$func$
BEGIN
RETURN QUERY EXECUTE format(
'SELECT t.cpa, substring(t.ku,'[0-9]+'), p.vym
FROM public."table_data_C" t
LEFT JOIN %s p USING (cpa)'
, 'pa' || _number
);
END
$func$ LANGUAGE plpgsql;
電話:
SELECT * FROM foo(456887)
通常、テーブル名はformat ( %I )
でサニタイズします。 SQLインジェクションを回避するため。 integer
だけで 必要のない動的入力として。この関連する回答の詳細とリンク:
トリガー関数に動的テーブル名を指定してINSERT
データモデル
データモデルには正当な理由があるかもしれません。パーティション分割/シャーディングまたは個別の特権のように...
そのような正当な理由がない場合は、同一のスキーマを持つ複数のテーブルを1つに統合し、number
を追加することを検討してください。 列として。そうすれば、動的SQLは必要ありません。
継承
を検討してください 。次に、tableoid
に条件を追加できます 特定の子テーブルからのみ行を取得するには:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
ただし、継承の制限に注意してください。 関連する回答:
1番目のテーブルの値に応じた2番目のテーブルの名前
最初のテーブルの値から結合テーブルの名前を取得すると、動的に複雑になります。
少数のテーブルのみ
LEFT JOIN
それぞれtableoid
。行ごとに一致するのは1つだけなので、COALESCE
を使用します 。
SELECT t.*, t.tbl, COALESCE(p1.vym, p2.vym, p3.vym) AS vym
FROM (
SELECT cpa, ('pa' || substring(ku,'[0-9]+'))::regclass AS tbl
FROM public."table_data_C"
-- WHERE <some condition>
) t
LEFT JOIN pa456887 p1 ON p1.cpa = t.cpa AND p1.tableoid = t.tbl
LEFT JOIN pa456888 p2 ON p2.cpa = t.cpa AND p2.tableoid = t.tbl
LEFT JOIN pa456889 p3 ON p3.cpa = t.cpa AND p3.tableoid = t.tbl
多くのテーブルの場合
ループと動的クエリを組み合わせる:
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS
$func$
DECLARE
_nr text;
BEGIN
FOR _nr IN
SELECT DISTINCT substring(ku,'[0-9]+')
FROM public."table_data_C"
LOOP
RETURN QUERY EXECUTE format(
'SELECT t.cpa, _nr, p.vym
FROM public."table_data_C" t
LEFT JOIN %I p USING (cpa)
WHERE t.ku LIKE (_nr || '%')'
, 'pa' || _nr
);
END LOOP;
END
$func$ LANGUAGE plpgsql;