Может ли аналитическая функция ссылаться на несколько строк в окне? - PullRequest
2 голосов
/ 11 января 2012

Дана таблица с:

    ID  VALUE
    --  -----
    1   1
    2   2
    3   3
    4   4

Я бы хотел вычислить что-то вроде этого:

    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 

Где сумма в каждой строке - это сумма значений каждой последующей строки, умноженная на разницу между значением следующей строки и текущей строки.

Я мог бы начать с чего-то вроде этого:

    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)

где каждая строка имеет сумму всех последующих строк. Но, если пойти дальше, мне бы очень хотелось что-то вроде этого псевдокода:

    SELECT id, value
          ,SUM( (value - FIRST_ROW(value)) * value )
             OVER(ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) AS sum
      FROM x;

Но это недопустимо. И в этом суть вопроса: есть ли способ ссылаться на несколько строк в окне аналитической функции? Или другой способ подойти к этому? Приведенный выше пример является надуманным. На самом деле я играл с интересной головоломкой из другого поста Rollup Query , которая привела меня к этой проблеме. Я пытаюсь сделать это в Postgresql 9.1, но не связан с этим.

1 Ответ

2 голосов
/ 11 января 2012

Не совсем уверен, понял ли я ваше требование именно здесь, но запрос, который вам нужен, выглядит примерно так:

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

Надеюсь, это поможет.

...