PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Tham gia bên trái với tên bảng động bắt nguồn từ cột

Dù bằng cách nào, bạn cũng cần SQL động.

Tên bảng dưới dạng tham số đã cho

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;

Gọi:

SELECT * FROM foo(456887)

Nói chung, bạn sẽ làm sạch tên bảng với định dạng format ( %I ) để tránh SQL injection. Chỉ với một số nguyên integer dưới dạng đầu vào động không cần thiết. Thêm chi tiết và liên kết trong câu trả lời có liên quan này:
CHÈN với tên bảng động trong chức năng kích hoạt

Mô hình dữ liệu

Có thể có những lý do chính đáng cho mô hình dữ liệu. Như phân vùng / sharding hoặc các đặc quyền riêng biệt ...
Nếu bạn không có lý do chính đáng như vậy, hãy xem xét việc hợp nhất nhiều bảng có giản đồ giống hệt nhau thành một và thêm number như cột. Sau đó, bạn không cần SQL động.

Xem xét kế thừa . Sau đó, bạn có thể thêm một điều kiện trên tableoid để chỉ truy xuất các hàng từ một bảng con đã cho:

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

Tuy nhiên, Hãy lưu ý các giới hạn đối với tính kế thừa. Các câu trả lời liên quan:

Tên của bảng thứ hai tùy thuộc vào giá trị trong bảng thứ nhất

Việc lấy tên của bảng nối từ các giá trị trong bảng đầu tiên sẽ tự động làm phức tạp mọi thứ.

Chỉ dành cho một vài bảng

LEFT JOIN mỗi trên tableoid . Chỉ có một kết quả phù hợp cho mỗi hàng, vì vậy hãy sử dụng 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

Đối với nhiều bảng

Kết hợp một vòng lặp với các truy vấn động:

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. Làm cách nào để thoát khỏi dấu nháy đơn trong truy vấn dòng lệnh của psql?

  2. Lưu trữ PostgreSQL được quản lý hoàn toàn trên AWS và Azure ra mắt kịp thời cho những lần di chuyển kế thừa

  3. Làm cách nào để xác định ngày cuối cùng của tháng trước bằng PostgreSQL?

  4. Tìm điểm gần nhất trong Pandas DataFrames

  5. Trong Postgres, làm cách nào để ĐẾM và ĐÂU trong cùng một truy vấn, sau đó thực hiện phép toán trên kết quả?