1

I have a larger query in which I have to select either the first or the last value for multiple columns.

So far I have the below structure for my query which works as intended.
However, since I have around 10 columns where for each of them I have to apply the same window function, i.e. the OVER (PARTITION BY ...) part (like for the sample columns col4 to col7 below), I was wondering if there is a way to write this just once instead of having to repeat the same lines each time.

I tried WINDOW w AS (...) after the FROM clause and then refered to this via OVER w AS ... for each column but that didn't work.

Can anyone here help me with this ?

My query structure (shortened):

SELECT DISTINCT
    c.col1
    , c.col2
    , c.col3
    , FIRST_VALUE(c.col4) OVER
        (
            PARTITION BY c.col1
            ORDER BY c.col1, c.col2, c.col3
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        ) AS col4
    , LAST_VALUE(c.col5) OVER
        (
            PARTITION BY c.col1
            ORDER BY c.col1, c.col2, c.col3
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        ) AS col5
    , LAST_VALUE(c.col6) OVER
        (
            PARTITION BY c.col1
            ORDER BY c.col1, c.col2, c.col3
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        ) AS col6
    , FIRST_VALUE(c.col7) OVER
        (
            PARTITION BY c.col1
            ORDER BY c.col1, c.col2, c.col3
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        ) AS col7
    /* ... */
FROM
    CUSTOMERS c
GROUP BY
    /* ... */
ORDER BY
    /* ... */

Many thanks in advance for any help with this

3
  • Show the version of your query is the window clause. It should work. Commented Apr 15, 2018 at 15:07
  • postgresql.org/docs/10/static/sql-select.html : WINDOW should come after the GROUP BY ... HAVING ...` clauses (but before the ORDER BY ...) Commented Apr 15, 2018 at 15:17
  • @wildplasser: Thanks for this comment ! That was the issue - I had put it before the GROUP BY. Commented Apr 15, 2018 at 15:19

1 Answer 1

4

WINDOW should come after the GROUP BY ... HAVING ... clauses (but before the ORDER BY ...) , as described in The Fine Manual

This should probably work:


SELECT DISTINCT
    c.col1 , c.col2 , c.col3
    , FIRST_VALUE(c.col4) OVER www AS col4
    , LAST_VALUE(c.col5) OVER www AS col5
    , LAST_VALUE(c.col6) OVER www AS col6
    , FIRST_VALUE(c.col7) OVER www AS col7
    /* ... */
FROM
    CUSTOMERS c
GROUP BY 1,2,3
WINDOW www AS (PARTITION BY c.col1
            ORDER BY c.col1, c.col2, c.col3
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        )
ORDER BY 1,2,3
        ;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.