Функция PostgreSQL для итерации / действия по многим строкам с состоянием - PullRequest
2 голосов
/ 09 июня 2010

У меня есть база данных со столбцами, похожими на:

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 ]

6 голосов
/ 09 июня 2010

Ну, это вряд ли красиво, но это функционально:

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 голос
/ 09 июня 2010

Чтобы использовать мой запрос, вам нужно начинать каждую транзакцию с записи SET 0.Кроме того, вы не сможете добавить другой тип, только SET и ADD будут работать, как я предлагаю.

Этот запрос не проверен.

Идея состоит в том, чтобы просто сложитьпоследний (самый окончательный) SET и каждый ADD, следующий за ним:

SELECT SUM(amt) 
    WHERE session=X 
      AND order >= ( SELECT MAX(order) 
                         WHERE atype='SET' 
                           AND session=X );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...