以值(来自另一个 table)作为参数的 Postgresql 函数

Postgresql function with values (from another table) as arguments

我不知道如何使用另一个 table 指定的输入来调用函数。

让我们假设使用以下函数来创建时间间隔:

create or replace function interval_generator(dt_start timestamp with TIME ZONE,
                                              dt_end timestamp with TIME ZONE,
                                              round_interval INTERVAL)
    returns TABLE(time_start timestamp with TIME ZONE,
                  time_end timestamp with TIME ZONE) as $$
BEGIN
return query
        SELECT
            (n)       time_start,
            (n + round_interval) time_end
        FROM generate_series(date_trunc('minute', dt_start), dt_end, round_interval) n;
END
$$
LANGUAGE 'plpgsql';

让我们为最小示例创建一个虚拟 table:

DROP TABLE IF EXISTS lookup;
CREATE TEMP TABLE lookup 
as 
select *
from (
   VALUES 
    ('2017-08-17 04:00:00.000'::timestamp), 
    ('2017-08-17 05:00:00.000'::timestamp), 
    ('2017-08-18 06:00:00.000'::timestamp)
) as t (datetime);

现在我的尝试如下:

select interval_generator(
    SELECT datetime FROM lookup Order By datetime limit 1,
    SELECT datetime FROM lookup Order By datetime Desc limit 1,
    '1 hours'::interval
);

它只会产生一般错误 ERROR: syntax error at or near "SELECT"

将 SELECT 语句括在括号中,使它们成为如下表达式:

select * from interval_generator(
    (SELECT datetime FROM lookup Order By datetime limit 1),
    (SELECT datetime FROM lookup Order By datetime Desc limit 1),
    '1 hours'::interval
);

请注意

SELECT datetime FROM lookup Order By datetime limit 1

正好是

SELECT min(datetime) FROM lookup

这在我看来更易读。由于 interval_generator 的函数体由单个 SQL 查询组成,为什么不将其设为普通的 SQL 函数而不是 pl/pgsql?

<your-function-declaration> as $$
 SELECT
   (n) time_start,
   (n + round_interval) time_end
 FROM generate_series(date_trunc('minute', dt_start), dt_end, round_interval) n;
$$
LANGUAGE 'sql';