2015-01-21 52 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