2015-01-21 43 views
1

我的數據:PostgreSQL的差異

id value 
1  10 
1  20 
1  60 
2  10 
3  10 
3  30 

如何計算列 '改變'?

id value change | my comment, how to compute 
1  10  10 | 20-10 
1  20  40 | 60-20 
1  60  40 | default_value-60. In this example default_value=100 
2  10  90 | default_value-10 
3  10  20 | 30-10 
3  30  70 | default_value-30 

換句話說:如果ID的行最後,然後計算100價值, 其他計算next_value-value_now

+0

你有unqiue或主鍵的最後一個值? – Mihai 2015-01-21 09:33:15

+0

獨特。想象一下,有日期列,我按它排列。 – Marta 2015-01-21 09:35:37

回答

1

您可以訪問的價值「下一個」(或「上」)行使用window function。如果您有一列用於定義行上的訂單,則「下一行」行的概念纔有意義。你說你有一個日期欄,您可以在其中訂購結果。我爲此使用了列名your_date_column。你需要用當然的實際列名替換它。

select id, 
     value, 
     lead(value, 1, 100) over (partition by id order by your_date_column) - value as change 
from the_table 
order by id, your_date_column 

lead(value, 1, 100)說:走 「下一個」 行的列value(這是1)。如果沒有這樣的行,請使用默認值100代替。

+0

default_value怎麼樣? – Marta 2015-01-21 09:39:55

+0

非常感謝,我會試試! :) – Marta 2015-01-21 09:41:56

+0

'coalesce(lead(value)over(由id按日期排序),100)'????? – 2015-01-21 11:04:25

1

加入一個子查詢和使用ROW_NUMBER找到每組

WITH CTE AS(
SELECT id,value, 
ROW_NUMBER() OVER (PARTITION BY id ORDER BY date) rn, 
(LEAD(value) OVER (PARTITION BY id ORDER BY date)-value) change FROM t) 
SELECT cte.id,cte.value, 
(CASE WHEN cte.change IS NULL THEN 100-cte.value ELSE cte.change END)as change FROM cte LEFT JOIN 
(SELECT id,MAX(rn) mrn FROM cte 
GROUP BY id) as x 
ON x.mrn=cte.rn AND cte.id=x.id 

FIDDLE

+1

爲什麼這個複雜的查詢嵌套?它是否比使用lead()提供的「簡單」訪問有什麼優勢? – 2015-01-21 10:07:16

+0

@a_horse_with_no_name對鉛的完整參數不太熟悉,用我所知道的做了。 – Mihai 2015-01-21 10:10:33