我需要能够过滤一个数据集,每3小时只显示第一个实例。如果发现了一个实例,那么之后3小时内发生的任何其他实例都应该被隐藏。
我所能找到的最接近的方法是使用 date_trunc
来获取每个小时的第一个实例,但我需要具体隐藏到第一个实例后的3个小时。
示例数据。
+------------------------+-------+
| Timestamp | Value |
+------------------------+-------+
| "2015-12-29 13:35:00" | 65 |
| "2015-12-29 13:40:00" | 26 |
| "2015-12-29 13:45:00" | 80 |
| "2015-12-29 13:50:00" | 10 |
| "2015-12-29 16:40:00" | 76 |
| "2015-12-29 16:45:00" | 73 |
| "2016-01-04 08:05:00" | 87 |
| "2016-01-04 08:10:00" | 90 |
| "2016-01-04 08:15:00" | 52 |
| "2016-01-04 08:20:00" | 90 |
| "2016-01-04 08:25:00" | 23 |
| "2016-01-04 08:30:00" | 96 |
| "2016-01-04 13:35:00" | 53 |
| "2016-01-04 13:40:00" | 15 |
| "2016-01-04 13:45:00" | 85 |
+------------------------+-------+
预期结果:
+------------------------+-------+
| Timestamp | Value |
+------------------------+-------+
| "2015-12-29 13:35:00" | 65 |
| "2015-12-29 16:40:00" | 76 |
| "2016-01-04 08:05:00" | 87 |
| "2016-01-04 13:30:00" | 7 |
+------------------------+-------+
Anyone have any ideas? Thank you so much for your help.
这是一个棘手的问题,因为你需要跟踪最后一个被选中的记录,以确定下一个记录--所以你不能只用 group by
间隔3小时。
这里有一个使用递归cte的方法。
with recursive cte(ts, value) as (
select ts, value
from mytable
where ts = (select min(ts) from mytable)
union all
select x.*
from (select ts from cte order by ts desc limit 1) c
cross join lateral (
select t.ts, t.value
from mytable t
where t.ts >= c.ts + interval '3' hour
order by t.ts
limit 1
) x
)
select * from cte order by ts
我们的想法是从表中最早的记录开始,然后选择至少3小时后的第一条可用记录进行迭代(假设时间戳列中没有重复的记录)。
需要注意的是 timestamp
并不是一个好的列名选择,因为它与语言关键字(那是一个数据类型)冲突。我把它改成了 ts
中的查询。
ts