按给定数量的行值进行分组

时间:2014-02-13 15:53:52

标签: sql postgresql group-by postgresql-8.4 greenplum

我在第1列中有一个值列表,现在我想得到下面5行值或6行值的总和,如下所示,并在适当的列中填充值。

enter image description here

例如,如果您看到列'next-5row-value'的第一行值将是从当前行到接下来的5行(将为9)的值的总和,而下一列将是下一列的总和该参考点的行值。

我正在尝试编写函数来循环以获得总和。有没有一种有效的方法。有人可以帮我吗。我正在使用postgres,greenplum。谢谢!

3 个答案:

答案 0 :(得分:2)

您可以尝试这样的事情:

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”列中使用NULL(对于6row是相同的),你可以使用返回第一个非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;

答案 1 :(得分:2)

例如,如果你有这个简单的表:

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

答案 2 :(得分:0)

我认为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;

如果数据库支持,使用窗口框架定义绝对是一种更好的方法。但上述情况也会奏效。