Динамически выполнять запрос, используя вывод другого запроса

У меня есть функция generate_table, которая принимает 2 входных параметра (rundate::date и branch::varchar)

Теперь я пытаюсь работать над второй функцией, используя PLPGSQL, которая получит список всех ветвей и самую новую дату для каждой ветви и передаст это как параметр функции generate_table.

У меня такой запрос:

select max(rundate) as rundate, branch
from t_index_of_imported_files
group by branch

и это приводит к этому:

rundate;branch 
2014-03-13;branch1
2014-03-12;branch2
2014-03-10;branch3
2014-03-13;branch4

и мне нужно, чтобы функция выполнялась примерно так

select generate_table('2014-03-13';'branch1');
select generate_table('2014-03-12';'branch2');
select generate_table('2014-03-10';'branch3');
select generate_table('2014-03-13';'branch4');

Я много читал о PLPGSQL, но пока могу только сказать, что едва знаю основы.

Я читал, что можно использовать конкатенацию, чтобы собрать все значения вместе, а затем использовать EXECUTE внутри функции, но я не мог заставить ее работать должным образом.

Любые предложения о том, как это сделать?


person Fulano da Silva Sauro    schedule 14.03.2014    source источник


Ответы (2)


Вы можете сделать это с помощью простого запроса SELECT, используя новый LATERAL JOIN< /strong> в Postgres 9.3+

SELECT *
FROM  (
   SELECT max(rundate) AS rundate, branch
   FROM   t_index_of_imported_files
   GROUP  BY branch
   ) t
 , generate_table(t.rundate, t.branch) g;  -- LATERAL is implicit here

Согласно документации:

LATERAL также может предшествовать элементу FROM вызова функции, но в данном случае это слово-помеха, поскольку выражение функции в любом случае может ссылаться на более ранние элементы FROM.

То же самое возможно в более старых версиях путем расширения строк для функций, возвращающих множество, в списке SELECT, но новый синтаксис с LATERAL намного чище. Во всяком случае, для Postgres 9.2 или старше:

SELECT generate_table(max(rundate), branch)
FROM   t_index_of_imported_files
GROUP  BY branch;
person Erwin Brandstetter    schedule 14.03.2014
comment
Ух ты! Гораздо проще, чем я думал! Большое спасибо всем, кто ответил! - person Fulano da Silva Sauro; 15.03.2014

Не нужно делать ничего сверхъестественного.

SELECT generate_table(rundate,branch) FROM (
    SELECT max(rundate) AS rundate, branch
    FROM t_index_of_imported_files
    GROUP BY branch) x;
person Dwayne Towell    schedule 14.03.2014
comment
Функции, возвращающие наборы, в SELECT устарели теперь, когда поддерживается LATERAL, и могут иметь странные и неожиданные результаты. - person Craig Ringer; 15.03.2014