如何在SQL中编写泛型和类型安全函数?

时间:2018-03-15 16:11:11

标签: sql postgresql

免责声明:我来自OO语言背景(主要是C ++),所以在回答我的问题时请考虑到这一点。

我有几个表都有timestamp列。现在我想创建一个以类型安全的方式创建一个JSON对象的函数,该对象保存属于这些表的某些行的minmax

为每个表以特殊的,重复的方式编写这些函数非常容易。但这会重复代码。这引出了我的问题。你如何编写优雅和通用的功能(虽然是类型安全的,也就是说,没有手动构建查询)?

在伪代码中,我正在寻找以下内容:

create function get_min_max(rows of tables which have timestamp colmn) returns json as $$
    select json_build_object('min', min(timestamp), 'max', max(timestamp))
    from $1;
$$ end;

select get_min_max(select * from my_table where some_condition);

1 个答案:

答案 0 :(得分:0)

您可以创建自定义聚合。

create or replace function timestamp_agg_function(jsonb, timestamp)
returns jsonb language plpgsql as $$
declare
    result jsonb;
begin
    if $1 is null then
        return jsonb_build_object('min', $2, 'max', $2);
    elseif $2 > ($1->>'max')::timestamp then
        return $1 || jsonb_build_object('max', $2);
    elsif $2 < ($1->>'min')::timestamp then
        return $1 || jsonb_build_object('min', $2);
    else
        return $1;
    end if;
end $$;

create aggregate timestamp_agg(timestamp) (
    sfunc = timestamp_agg_function,
    stype = jsonb);

使用示例:

with my_table(tstamp) as (
values
    ('2018-03-20'),
    ('2018-03-10'),
    ('2018-03-30')
)

select timestamp_agg(tstamp::timestamp)
from my_table;

                        timestamp_agg                         
--------------------------------------------------------------
 {"max": "2018-03-30T00:00:00", "min": "2018-03-10T00:00:00"}
(1 row)

请阅读文档中的更多内容:User-defined AggregatesCREATE AGGREGATE.