我正在尝试将postgresql查询转换为plr函数

我正在尝试将postgresql查询转换为plr函数,sql,r,postgresql,plr,Sql,R,Postgresql,Plr,我有一个postgres查询,当我将其作为查询运行时,它可以正常工作。但是,我希望将其转换为pl/r,并能够动态输入开始和结束日期 有效的SQL是: with date as ( select d as first_day, d + interval '1 month' - interval '1 day' as last_day from generate_series('2010-01-01'::date, '2018-12-01'::date,

我有一个postgres查询,当我将其作为查询运行时,它可以正常工作。但是,我希望将其转换为pl/r,并能够动态输入开始和结束日期

有效的SQL是:

with date as (
select d as first_day,
d + interval '1 month' - interval '1 day' as last_day
from generate_series('2010-01-01'::date,
                     '2018-12-01'::date,
                     '1 month') as d
) select last_day::date as snapshot_date from date;
我想做一个损益表,如:

DROP FUNCTION IF EXISTS standard.seq_monthly(min_date_str char, max_date_str char);
CREATE FUNCTION standard.seq_monthly(min_date_str char, max_date_str char)
RETURNS setof dates AS
$$ 
with date as (
select d as first_day,
d + interval '1 month' - interval '1 day' as last_day
from generate_series(min_date_str::date,
                     max_date_str::date,
                     '1 month') as d
) select last_day::date as snapshot_date from date;

$$
LANGUAGE 'plr';
select * from standard.seq_monthly('2010-01-01' , '2018-12-01')
但是,我在运行函数时出错。错误是


在PLR711818中捕获的R解析错误解决方案之一是不通过plr,而是编写sql查询:

with max_min_date as(
select max(snapshot_date) as max_date_str, min(snapshot_date) as min_date_str from data
) , 
ts as (
select d as first_day,
d + interval '1 month' - interval '1 day' as last_day
from generate_series((select min_date_str from max_min_date)::date,
                     (select max_date_str from max_min_date)::date,
                     '1 month') as d
) select last_day::date as snapshot_date from ts;
在这种情况下,您需要月底日期而不是月初日期:

with max_min_date as(
  with max_min_wrk as (
    select max(snapshot_date) as max_date_str, min(snapshot_date) as min_date_str from data
    ) select cast(date_trunc('month', max_date_str) as date) as max_date, cast(date_trunc('month', min_date_str) as date) as min_date from max_min_wrk
), 
ts as (
select d as first_day,
d + interval '1 month' - interval '1 day' as last_day
from generate_series((select min_date from max_min_date)::date,
                     (select max_date from max_min_date)::date,
                     '1 month') as d
) select last_day::date as snapshot_date from ts 
order by snapshot_date asc;
PL/R是PostgreSQL中的一个扩展,类似于plpython、plperl、plphp,其中可以运行有效的、兼容的R语言代码。您尝试的SQL本身无法在R会话中运行,因此您的代码将在PG plr存储函数中失败

但是,不需要这样的扩展,因为可以使用非常基本的SQL语言来处理您的需要,通过指定的输入范围返回所需的日期范围表通常效率更高:

创建或替换函数seq_monthlymin_date_str char、max_date_str char 将TABLEsnapshot\u日期返回为 $$ 以mydate为例 选择d作为第一天, 年月日 +“1个月”:间隔 -“1天”:间隔为最后一天 从generate_seriesmin_date_str::date, 最大日期长度::日期, “1个月”作为d 从mydate中选择last_day::date作为快照_日期; $$ 语言SQL稳定; 从seq_月刊“2010-01-31”、“2018-12-31”中选择*; 现在,如果您真的想要plr存储函数,请在给定的日期范围内使用R的seq:

创建函数standard.seq_monthlymin_date_str char,max_date_str char 将日期集返回为 $$ seqas.Datemin_date_str,as.Datemax_date_str,by='month' $$ 语言“plr”; 从标准中选择*。seq_月刊'2010-01-01','2018-12-01'
PL/R需要R代码而不是SQL。顺便说一句,使用SQL比任何过程扩展(包括Postgres的内置plpgsql)都更有效。顺便说一句:date几乎是一个保留字。你可能会输,现在或将来。但这如何解决将日期作为参数传递的问题呢?我使用现有数据中的日期,这是将日期作为参数传递的最初动机。通过发布的数据和更多信息,我们可以得出相同的结论。绝对同意你的观点。抱歉,上面有点小的改进,因为我想要月底的日期,而不是月初的日期。不知怎的,这两个都不适合我写博士后。此外,该错误没有任何解释。只是说错误!可能是我或我的博士后版本。我会再次查看shortlyon rextester演示链接,尝试传递月份的最后日期,因为可爱的二月的天数缩短了,此后模式也会随之改变。然而,有一种更好的方法来处理DATE_TRUNC。查看更新的答案和演示链接。完美!非常感谢。使用作者的,其中包括html/pdf文档,包括安装步骤。顺便说一句,作者就是帮助RPostgreSQL,R包的那个人。