PostgreSQL函数迭代/处理许多行状态

时间:2010-06-08 21:48:08

标签: sql postgresql

我有一个数据库,其列如下:

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进行任何类似迭代的事情,或者根本不可能。

2 个答案:

答案 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记录开始每个事务。此外,您将无法添加其他类型,只有SETADD才能正常工作。

此查询未经测试。

这个想法是简单地总结最新的(最终的)SET和跟随它的每个ADD

SELECT SUM(amt) 
    WHERE session=X 
      AND order >= ( SELECT MAX(order) 
                         WHERE atype='SET' 
                           AND session=X );