Can window function LAG reference the column which value is being calculated?

前端 未结 3 758
北海茫月
北海茫月 2021-01-18 01:30

I need to calculate value of some column X based on some other columns of the current record and the value of X for the previous record (using some partition and order). Bas

3条回答
  •  刺人心
    刺人心 (楼主)
    2021-01-18 02:04

    An alternative to a recursive approach is a custom aggregate. Once you master the technique of writing your own aggregates, creating transition and final functions is easy and logical.

    State transition function:

    create or replace function is_duplicate(st int[], time_stamp int, timeframe int)
    returns int[] language plpgsql as $$
    begin
        if st is null or st[1] + timeframe <= time_stamp
        then 
            st[1] := time_stamp;
        end if;
        st[2] := time_stamp;
        return st;
    end $$;
    

    Final function:

    create or replace function is_duplicate_final(st int[])
    returns boolean language sql as $$
        select st[1] <> st[2];
    $$;
    

    Aggregate:

    create aggregate is_duplicate_agg(time_stamp int, timeframe int)
    (
        sfunc = is_duplicate,
        stype = int[],
        finalfunc = is_duplicate_final
    );
    

    Query:

    select *, is_duplicate_agg(time_stamp, 10) over w
    from event
    window w as (partition by type order by time_stamp asc)
    order by type, time_stamp;
    
     id | type | time_stamp | is_duplicate_agg 
    ----+------+------------+------------------
      1 |    1 |          1 | f
      2 |    1 |          2 | t
      4 |    1 |          3 | t
      5 |    1 |         10 | t
      7 |    1 |         15 | f
      8 |    1 |         21 | t
     10 |    1 |         40 | f
      3 |    2 |          2 | f
      6 |    2 |         10 | t
      9 |    2 |         13 | f
    (10 rows)   
    

    Read in the documentation: 37.10. User-defined Aggregates and CREATE AGGREGATE.

提交回复
热议问题