I have a Postgres table writing every minute int value (requests count).
I have some requests types on some servers, all of them on the same table:
time | key1 | key2 | key3 | value
-----------------------------------------------------------------------
2017-01-16 18:00:53 | server1 | webpage1 | type1 | 30
2017-01-16 18:00:55 | server1 | webpage2 | type1 | 31
2017-01-16 18:00:58 | server1 | webpage3 | type1 | 32
2017-01-16 18:00:59 | server1 | webpage4 | type1 | 33
2017-01-16 18:01:00 | server1 | webpage5 | type1 | 34
2017-01-16 18:01:01 | server1 | webpage6 | type1 | 35
2017-01-16 18:01:02 | server1 | webpage7 | type1 | 36
2017-01-16 18:01:03 | server1 | webpage8 | type1 | 37
2017-01-16 18:01:04 | server1 | webpage1 | type1 | 56
2017-01-16 18:01:06 | server1 | webpage2 | type1 | 35
2017-01-16 18:01:07 | server1 | webpage3 | type1 | 43
2017-01-16 18:01:10 | server1 | webpage4 | type1 | 64
2017-01-16 18:01:13 | server1 | webpage5 | type1 | 44
2017-01-16 18:01:14 | server1 | webpage6 | type1 | 66
2017-01-16 18:01:16 | server1 | webpage7 | type1 | 56
2017-01-16 18:01:18 | server1 | webpage8 | type1 | 22
Assume key1 and key3 has different values as well (for the sake of this example I emitted some data).
I need the result to be the diff of the latest value on group (key1, key2, key3) minus the 1 offset of the latest [I need the rate per minute].
I successfully got the result of the latest and 1 offset of it in the same table (grouped by key):
SELECT * FROM
(SELECT ROW_NUMBER()
OVER(PARTITION BY key1, key2, key3 ORDER BY time DESC) as rnum,
time, key1, key2, key3, value FROM test ORDER BY time DESC) a
WHERE rnum < 3;
So the result is:
rnum | time | key1 | key2 | key3 | value
------+---------------------+---------+----------+-------+-------
1 | 2017-01-16 18:01:18 | server1 | webpage8 | type1 | 22
1 | 2017-01-16 18:01:16 | server1 | webpage7 | type1 | 56
1 | 2017-01-16 18:01:14 | server1 | webpage6 | type1 | 66
1 | 2017-01-16 18:01:13 | server1 | webpage5 | type1 | 44
1 | 2017-01-16 18:01:10 | server1 | webpage4 | type1 | 64
1 | 2017-01-16 18:01:07 | server1 | webpage3 | type1 | 43
1 | 2017-01-16 18:01:06 | server1 | webpage2 | type1 | 35
1 | 2017-01-16 18:01:04 | server1 | webpage1 | type1 | 56
2 | 2017-01-16 18:01:03 | server1 | webpage8 | type1 | 37
2 | 2017-01-16 18:01:02 | server1 | webpage7 | type1 | 36
2 | 2017-01-16 18:01:01 | server1 | webpage6 | type1 | 35
2 | 2017-01-16 18:01:00 | server1 | webpage5 | type1 | 34
2 | 2017-01-16 18:00:59 | server1 | webpage4 | type1 | 33
2 | 2017-01-16 18:00:58 | server1 | webpage3 | type1 | 32
2 | 2017-01-16 18:00:55 | server1 | webpage2 | type1 | 31
2 | 2017-01-16 18:00:53 | server1 | webpage1 | type1 | 30
Now, I thought i can take the value column of MIN(time) and MAX(time) and calc the diff, but I cannot "merge" the lines.
After @HartCO Comment I was able to do this:
select time, new_val-last_val, key1, key2, key3 from
(select distinct max(time) over(partition by key1, key2, key3) as time,
max(value) over(partition by key1, key2, key3) as new_val,
min(value) over(partition by key1, key2, key3) as last_val,
key1, key2, key3
from (select row_number() over(partition by key1, key2, key3 order by time desc) as rnum,
time, key1, key2, key3, value from test order by time desc) a
where rnum < 3) b;
And I got:
time | ?column? | key1 | key2 | key3
---------------------+----------+---------+----------+-------
2017-01-16 18:01:14 | 31 | server1 | webpage6 | type1
2017-01-16 18:01:18 | 15 | server1 | webpage8 | type1
2017-01-16 18:01:16 | 20 | server1 | webpage7 | type1
2017-01-16 18:01:04 | 26 | server1 | webpage1 | type1
2017-01-16 18:01:13 | 10 | server1 | webpage5 | type1
2017-01-16 18:01:06 | 4 | server1 | webpage2 | type1
2017-01-16 18:01:07 | 11 | server1 | webpage3 | type1
2017-01-16 18:01:10 | 31 | server1 | webpage4 | type1
But the desired output should be -15 on webpage8, not 22.