问题
Given a table with:
ID VALUE
-- -----
1 1
2 2
3 3
4 4
I would like to compute something like this:
ID VALUE SUM
-- ----- ---
1 1 40 -- (2-1)*2 + (3-1)*3 + (4-1)*4 + (5-1)*5
2 2 26 -- (3-2)*3 + (4-2)*4 + (5-2)*5
3 3 14 -- (4-3)*4 + (5-3)*5
4 4 5 -- (5-4)*5
5 5 0 -- 0
Where the SUM on each row is the sum of the values of each subsequent row multiplied by the difference between the value of the subsequent row and the current row.
I could start with something like this:
CREATE TABLE x(id int, value int);
INSERT INTO x VALUES(1, 1);
INSERT INTO x VALUES(2, 2);
INSERT INTO x VALUES(3, 3);
INSERT INTO x VALUES(4, 4);
INSERT INTO x VALUES(5, 5);
SELECT id, value
,SUM(value) OVER(ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) AS sum
FROM x;
id | value | sum
----+-------+-----
1 | 1 | 14
2 | 2 | 12
3 | 3 | 9
4 | 4 | 5
5 | 5 |
(5 rows)
where each row has the sum of all subsequent rows. But to take it further, I would really want something like this pseudo code:
SELECT id, value
,SUM( (value - FIRST_ROW(value)) * value )
OVER(ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) AS sum
FROM x;
But this is not valid. And that is the crux of the question: is there a way to reference multiple rows in the window of an analytic function? Or a different way to approach this? The example above is contrived. I was actually playing with an interesting puzzle from another post Rollup Query which led me to this problem. I am trying this in Postgresql 9.1, but not bound to that.
回答1:
Not quite sure if I've understood your requirement exactly here, but the query that you want is something like
select a.id, a.value, sum(( b.value - a.value ) * b.value )
from x a, x b
where a.id < b.id
group by a.id, a.value
Hope that helps.
来源:https://stackoverflow.com/questions/8813743/can-multiple-rows-within-a-window-be-referenced-by-an-analytic-function