我有这张桌子
create table events
(
event_type integer not null,
value integer not null,
time timestamp not null,
unique(event_type, time)
);
我想编写一个SQL查询,对于每个已多次注册的SQL查询,返回的是最新的(即,最新的)与第二个最新的之间的差额。该表应按(升序)排序。
样本数据为:
event_type | value | time
-------------+------------+--------------------
2 | 5 | 2015-05-09 12:42:00
4 | -42 | 2015-05-09 13:19:57
2 | 2 | 2015-05-09 14:48:30
2 | 7 | 2015-05-09 12:54:39
3 | 16 | 2015-05-09 13:19:57
3 | 20 | 2015-05-09 15:01:09
输出应为
event_type | value
------------+-----------
2 | -5
3 | 4
到目前为止,我尝试这样做
SELECT event_type
FROM events
GROUP BY event_type
HAVING COUNT(event_type) > 1
ORDER BY event_type
我找不到第二种方法为我提到的第二列获取正确的值。我正在使用PostgreSQL 9.4
答案 0 :(得分:1)
您可以使用ANSI / ISO标准窗口功能执行此操作:
select event_type,
sum(case when seqnum = 1 then value
when seqnum = 2 then - value
end) as diff_latest
from (select e.*,
row_number() over (partition by event_type order by time desc) as seqnum
from events e
) e
where seqnum in (1, 2)
group by event_type
having count(*) = 2;
Here是一个SQL提琴。
答案 1 :(得分:1)
使用lead
的一种方法,该方法根据指定的顺序获取给定列的下一个值。给定event_type的倒数第二行将具有最新值,在这种情况下可用于减去。 (运行内部查询以了解如何分配next_val
)
select event_type,next_val-value as diff
from (select t.*
,lead(value) over(partition by event_type order by time) as next_val,
,row_number() over(partition by event_type order by time desc) as rnum
from tbl t
) t
where next_val is not null and rnum=2
还有一个DISTINCT ON
和lead
的选项。
select distinct on (event_type) event_type,next_val-value as diff
from (select t.*,lead(value) over(partition by event_type order by time) as next_val
from events t
) t
where next_val is not null
order by event_type,time desc