我有一个数据库,其列如下:
session | order | atype | amt
--------+-------+-------+-----
1 | 0 | ADD | 10
1 | 1 | ADD | 20
1 | 2 | SET | 35
1 | 3 | ADD | 10
2 | 0 | SET | 30
2 | 1 | ADD | 20
2 | 2 | SET | 55
它代表正在发生的行动。每个会话从0开始.ADD添加一个数量,而SET设置它。我想要一个函数来返回会话的结束值,例如
SELECT session_val(1); --returns 45
SELECT session_val(2); --returns 55
是否可以编写这样的函数/查询?我不知道如何使用SQL进行任何类似迭代的事情,或者根本不可能。
答案 0 :(得分:6)
嗯,这很不错,但它很实用:
select sum(amt) as session_val
from (
select segment,
max(segment) over() as max_segment,
amt
from (
select sum(case when atype = 'SET' then 1 else 0 end)
over(order by "order") as segment,
amt
from command
where session = 2
) x
) x
where segment = max_segment
虽然PL / pgsql很简单:
create function session_val(session int) returns int stable strict
language plpgsql as $$
declare
value int := 0;
rec command%rowtype;
begin
for rec in select * from command where command.session = session_val.session loop
if rec.atype = 'SET' then
value := rec.amt;
elsif rec.atype = 'ADD' then
value := value + rec.amt;
end if;
end loop;
return value;
end $$;
所以请你选择,我猜。
答案 1 :(得分:1)
要使用我的查询,您需要使用SET 0
记录开始每个事务。此外,您将无法添加其他类型,只有SET
和ADD
才能正常工作。
此查询未经测试。
这个想法是简单地总结最新的(最终的)SET
和跟随它的每个ADD
:
SELECT SUM(amt)
WHERE session=X
AND order >= ( SELECT MAX(order)
WHERE atype='SET'
AND session=X );