sql >> データベース >  >> RDS >> PostgreSQL

列から派生した動的テーブル名を使用した左結合

    いずれにせよ、動的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;
    



    1. SQL クエリから Excel で Clob データ型を処理する方法

    2. LIMITMySQLを使用した複数のWHERE

    3. postgresqlがJSONをJSONBに移行する

    4. postgresqlでsymfonyを使用する