Search code examples
sqlpostgresqlwindow-functions

Group repeated OVER clauses together in Postgres


Is it possible to somehow combine several repeated OVER clauses together in Postgres?

Example with a CASE ... END scenario:

   case
        when hhk = lag(hhk) over (order by hhk, product, dt)
        and product = lag(product) over (order by hhk, product, dt)
        then dt - lag(dt) over (order by hhk, product, dt)
        else null
    end as delta

The clause over (order by hhk, product, dt) is repeated three times. I'm looking for a way to somehow group them together, like the following (which of course doesn't work as such):

    case
        -- here we combine the two conditions into one
        when [hhk, product] = lag([hhk, product]) 
            over (order by hhk, product, dt)
        -- and here we somehow recall the clause
        then dt - lag(dt) over (my_clause)
        else null
    end as delta

Solution

  • You can define a window in the FROM clause. For example:

    select v.*, row_number() over w
    from (values (1, 2), (1, 3)) v(x, y)
         window w as (partition by x order by y)
    

    In your specific example, I can speculate something like this:

    select . . .
           (case when household_key = lag(household_key) over w and
                      product_id = lag(product_id) over w
            then dt - lag(dt) over w
            end) as delta
    from . . .
         window w as (order by household_key, product_id, dt)