我在第 1 列中有一个值列表,现在我想获得下一个 5 行值或 6 个行值的总和,如下所示,并将值填充到适当的列中。
例如,如果您看到“next-5row-value”列的第一行值将是从当前行到接下来 5 行的值的总和,即 9,下一列将是接下来 5 行值的总和那个参考点。
我正在尝试编写函数来循环得出总和。有没有有效的方法。有人可以帮我吗。我正在使用 postgres,greenplum。谢谢!
我在第 1 列中有一个值列表,现在我想获得下一个 5 行值或 6 个行值的总和,如下所示,并将值填充到适当的列中。
例如,如果您看到“next-5row-value”列的第一行值将是从当前行到接下来 5 行的值的总和,即 9,下一列将是接下来 5 行值的总和那个参考点。
我正在尝试编写函数来循环得出总和。有没有有效的方法。有人可以帮我吗。我正在使用 postgres,greenplum。谢谢!
例如,如果你有这个简单的表:
sebpa=# \d numbers
Table "public.numbers"
Column | Type | Modifiers
--------+---------+------------------------------------------------------
id | integer | not null default nextval('numbers_id_seq'::regclass)
i | integer |
sebpa=# select * from numbers limit 15;
id | i
------+---
3001 | 3
3002 | 0
3003 | 5
3004 | 1
3005 | 1
3006 | 4
3007 | 1
3008 | 1
3009 | 4
3010 | 0
3011 | 4
3012 | 0
3013 | 3
3014 | 2
3015 | 1
(15 rows)
你可以使用这个 sql:
sebpa=# select id, i, sum(i) over( order by id rows between 0 preceding and 4 following) from numbers;
id | i | sum
------+---+-----
3001 | 3 | 10
3002 | 0 | 11
3003 | 5 | 12
3004 | 1 | 8
3005 | 1 | 11
3006 | 4 | 10
3007 | 1 | 10
3008 | 1 | 9
3009 | 4 | 11
3010 | 0 | 9
3011 | 4 | 10
3012 | 0 | 10
3013 | 3 | 13
3014 | 2 | 15
3015 | 1 | 17
3016 | 4 | 20
3017 | 3 | 17
--cutted output
你可以尝试这样的事情:
SELECT V,
SUM(V) OVER(ORDER BY YourOrderingField
ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING) AS next_5row_value,
SUM(V) OVER(ORDER BY YourOrderingField
ROWS BETWEEN 1 FOLLOWING AND 6 FOLLOWING) AS next_6row_value
FROM YourTable;
如果您不想在“next_5row_value”列(第 6 行相同)中出现 NULL,则可以使用返回第一个非空表达式的 COALESCE 函数(PostgreSQL 也支持)。像这样的东西:
SELECT V,
COALESCE(SUM(V) OVER(ORDER BY YourOrderingField
ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING), 0) AS next_5row_value,
COALESCE(SUM(V) OVER(ORDER BY YourOrderingField
ROWS BETWEEN 1 FOLLOWING AND 6 FOLLOWING), 0) AS next_6row_value
FROM YourTable;
我不认为 Postgres 8.4 支持窗口框架的全部功能。您可以使用以下方法执行此操作lead()
:
select value,
(value +
lead(value, 1) over (order by id) +
lead(value, 2) over (order by id) +
lead(value, 3) over (order by id) +
lead(value, 4) over (order by id)
) as next5,
(value +
lead(value, 1) over (order by id) +
lead(value, 2) over (order by id) +
lead(value, 3) over (order by id) +
lead(value, 4) over (order by id) +
lead(value, 5) over (order by id)
) as next5
from table t;
如果数据库支持,使用窗框定义绝对是更好的方法。但是上面的方法也可以。