2014-02-13 20 views
1

我有列1中的值列表,現在我想要得到下面5行值或6行值的總和,如下所示,並將值填充到適當的列中。按給定數量的行值進行分組

enter image description here

例如如果看到該列的第一行的值的下-5row值'是從當前行的值的總和到下一個5行這將是9和下一列將是來自該參考點的下5行值的總和。

我正在努力編寫函數來循環到達總和。有沒有一種有效的方法。有人可以幫我嗎。我正在使用postgres,greenplum。謝謝!

+0

表本質上是無序的。你有沒有指定排序的列(比如自動遞增的id或創建日期/時間)? –

+0

@GordonLinoff是的我有周末的日期來指。現在它變成了這個問題。來自給定參考點的未來五週的價值 – user2569524

回答

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 
+0

如果特定條目之後沒有5,該怎麼辦?有沒有辦法在列next-5row-value中用null或0替換那些條目? – user2569524

+0

它也可以運行http://pastebin.com/yvFJLjEu – sebpa

+1

你需要添加一個CASE WHEN COUNT(*)(在當前行和下一個4之間的id行排序)= 5然後總結(i)結束(按ID排序當前行與下列4行之間的行)END – dnoeth

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」列(同爲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; 
+0

這是否適用於Postgres 8.4? –

+0

@Corrado如果某個特定條目之後沒有5,該怎麼辦?有沒有辦法在列next-5row-value中用null或0替換那些條目? – user2569524

+0

當你得到NULL時,你想要0?對? –

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; 

使用窗框的定義無疑是一個更好的方法,如果數據庫支持。但上述也將起作用。

+0

如果沒有5個特定條目後面怎麼辦?有沒有辦法在列next-5row-value中用null或0替換那些條目? – user2569524

+0

@ user2569524。 。 。這自動處理這種情況。 'lead()'將返回NULL,這將導致整個和爲NULL。 –

+0

但說我必須考慮52個值低於某個參考點,在這種方法中,我需要寫這些條目52次。有沒有辦法來處理這個問題。或者我們只是把它放在一個函數內的循環中? – user2569524