PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Gabung kiri dengan nama tabel dinamis yang berasal dari kolom

Bagaimanapun, Anda memerlukan SQL dinamis.

Nama tabel sebagai parameter yang diberikan

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;

Telepon:

SELECT * FROM foo(456887)

Umumnya, Anda akan membersihkan nama tabel dengan format ( %I ) untuk menghindari injeksi SQL. Hanya dengan integer sebagai input dinamis yang tidak perlu. Detail lebih lanjut dan tautan dalam jawaban terkait ini:
MASUKKAN dengan nama tabel dinamis dalam fungsi pemicu

Model data

Mungkin ada alasan bagus untuk model data. Seperti mempartisi / membagi atau memisahkan hak istimewa ...
Jika Anda tidak memiliki alasan yang baik, pertimbangkan untuk menggabungkan beberapa tabel dengan skema yang identik menjadi satu dan tambahkan number sebagai kolom. Maka Anda tidak perlu SQL dinamis.

Pertimbangkan inheritance . Kemudian Anda dapat menambahkan kondisi pada tableoid untuk hanya mengambil baris dari tabel anak yang diberikan:

SELECT * FROM parent_table
WHERE  tableoid = 'pa456887'::regclass

Namun, perhatikan batasan untuk pewarisan. Jawaban terkait:

Nama tabel ke-2 tergantung nilai di tabel ke-1

Menurunkan nama tabel gabungan dari nilai di tabel pertama secara dinamis memperumit banyak hal.

Hanya untuk beberapa tabel

LEFT JOIN masing-masing di tableoid . Hanya ada satu kecocokan per baris, jadi gunakan 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

Untuk banyak tabel

Gabungkan loop dengan kueri dinamis:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tidak dapat menginstal plpython3u - postgresql

  2. Dapatkan tanggal pertama bulan di postgres

  3. String Koneksi PostgreSQL dengan driver ODBC di C#, Kata kunci tidak didukung:driver

  4. Bagaimana cara menerapkan pagination ke hasil kueri SQL dengan Gabung?

  5. Terapkan filter pencarian untuk semua kolom