Is it possible to apply multiple window functions to the same partition? (Correct me if I'm not using the right vocabulary)
For example you can do
SELECT name, first_value() over (partition by name order by date) from table1
But is there a way to do something like:
SELECT name, (first_value() as f, last_value() as l (partition by name order by date)) from table1
Where we are applying two functions onto the same window?
Reference: http://postgresql.ro/docs/8.4/static/tutorial-window.html
Can you not just use the window per selection
Something like
Also from your reference you can do it like this
Warning : I don't delete this answer since it seems technically correct and therefore may be helpful, but beware that
PARTITION BY bar ORDER BY foo
is probably not what you want to do anyway. Indeed, aggregate functions won't compute the partition elements as a whole. That is,SELECT avg(foo) OVER (PARTITION BY bar ORDER BY foo)
is not equivalent toSELECT avg(foo) OVER (PARTITION BY bar)
(see proof at the end of the answer).Though it doesn't improve performance per se, if you use multiple times the same partition, you probably want to use the second syntax proposed by astander, and not only because it's cheaper to write. Here is why.
Consider the following query :
Since in principle the ordering has no effect on the computation of the average, you might be tempted to use the following query instead (no ordering on the second partition) :
This is a big mistake, as it will take much longer. Proof :
Now, if you are aware of this issue, of course you will use the same partition everywhere. But when you have ten times or more the same partition and you are updating it over days, it is quite easy to forget to add the
ORDER BY
clause on a partition which doesn't need it by itself.Here comes the
WINDOW
syntax, which will prevent you from such careless mistakes (provided, of course, you're aware it's better to minimize the number of different window functions). The following is strictly equivalent (as far as I can tell fromEXPLAIN ANALYZE
) to the first query :Post-warning update :
I understand the statement that "
SELECT avg(foo) OVER (PARTITION BY bar ORDER BY foo)
is not equivalent toSELECT avg(foo) OVER (PARTITION BY bar)
" seems questionable, so here is an example :