我的代码适用于3个cols(id | timestamp | value
)的数据集(=多行)并生成单个数字结果(得分)。
现在我想把这段代码放在一个函数中,以便我可以重用它。假设我有4个其他查询都生成了包含这3个cols的数据集,我想从中计算得分,而不必复制/粘贴我的代码......我怎么能这样做?似乎无法将TABLE(...)
类型作为函数参数传递。
我认为我不能使用聚合函数,因为我的评分代码会在内部添加新行,对它们进行分组等等。我需要同时处理所有行并且没有状态转换。
答案 0 :(得分:2)
这个问题非常有趣,因为它反映了自定义聚合函数的非标准使用。
(...)设想一些查询首先按行对行进行排序,然后相乘 第一个row.value,其值为4th,并将其设置为new 第一行的值。然后它返回第一个值< 5 as 得分。
我们需要:
create type scores as (id int, val numeric);
create function save_scores(p scores, n scores)
returns scores language plpgsql as $$
begin
if p is null then
create temp table temp_scores of scores;
end if;
insert into temp_scores values (n.id, n.val);
return n;
end $$;
create function calculate_scores(t scores)
returns numeric language plpgsql as $$
declare
id1 int;
val4 numeric;
res numeric;
begin
select id into id1 from temp_scores order by id limit 1;
select val into val4 from temp_scores order by id offset 3 limit 1;
update temp_scores set val = val* val4 where id = id1;
select val into res from temp_scores where val < 5 order by id limit 1;
drop table temp_scores;
return res;
end $$;
汇总:
create aggregate get_scores(scores) (
sfunc = save_scores,
finalfunc = calculate_scores,
stype = scores
);
和一些检查:
select get_scores(row)
from (
values (4, 3.1), (3, 1.2), (2, 5.2), (1, 2)
) row
-- gives 1.2
select get_scores(row)
from (
values (4, 3.1), (3, 1.2), (2, 5.2), (1, 1)
) row
-- gives 3.1
由于使用临时表,聚合只能在一个查询中使用一次。为简单起见,省略了列timestamp
。