PostgreSQL
 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 с име на динамична таблица във функция за задействане

Модел на данни

Може да има основателни причини за модела на данни. Като разделяне/шардинг или отделни привилегии...
Ако нямате толкова основателна причина, помислете за консолидиране на няколко таблици с идентична схема в една и добавете number като колона. Тогава нямате нужда от динамичен SQL.

Помислете за наследяване . След това можете да добавите условие към tableoid за извличане само на редове от дадена дъщерна таблица:

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

Все пак имайте предвид ограниченията за наследяването. Свързани отговори:

Име на 2-ра таблица в зависимост от стойността в 1-ва таблица

Извличането на името на таблицата за свързване от стойностите в първата таблица динамично усложнява нещата.

Само за няколко маси

LEFT JOIN всеки на tableoid . Има само едно съвпадение на ред, така че използвайте 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Django:изберете стойности с максимални времеви марки или се присъединете към същата таблица

  2. Изключете паралелно множество масиви

  3. Как работи Width_Bucket() в PostgreSQL

  4. Проблеми със заявките за SQLite3 и Postgres/Heroku Ruby on Rails

  5. PostgreSQL връща точна или най-близка дата до заявената дата