我有一个表,它存储一段时间内网络上的带宽使用情况。一列将包含日期时间(主键),另一列将记录带宽。每分钟记录一次数据。我们将在其他列中及时记录其他数据。
如果用户每隔 15 分钟请求数据(在给定开始和结束日期的 24 小时内),是否可以通过单个查询来获取我需要的数据,或者我是否必须编写存储过程/游标来执行此操作? 然后用户可以请求 5 分钟间隔数据等。
我很可能会使用 Postgres,但还有其他更好的 NOSQL 选项吗?
有任何想法吗?
我有一个表,它存储一段时间内网络上的带宽使用情况。一列将包含日期时间(主键),另一列将记录带宽。每分钟记录一次数据。我们将在其他列中及时记录其他数据。
如果用户每隔 15 分钟请求数据(在给定开始和结束日期的 24 小时内),是否可以通过单个查询来获取我需要的数据,或者我是否必须编写存储过程/游标来执行此操作? 然后用户可以请求 5 分钟间隔数据等。
我很可能会使用 Postgres,但还有其他更好的 NOSQL 选项吗?
有任何想法吗?
WITH t AS (
SELECT ts, (random()*100)::int AS bandwidth
FROM generate_series('2012-09-01', '2012-09-04', '1 minute'::interval) ts
)
SELECT date_trunc('hour', ts) AS hour_stump
,(extract(minute FROM ts)::int / 15) AS min15_slot
,count(*) AS rows_in_timeslice -- optional
,sum(bandwidth) AS sum_bandwidth
FROM t
WHERE ts >= '2012-09-02 00:00:00+02'::timestamptz -- user's time range
AND ts < '2012-09-03 00:00:00+02'::timestamptz -- careful with borders
GROUP BY 1, 2
ORDER BY 1, 2;
CTE 提供的数据类似于您的表可能包含的数据:每分钟一个带有数字的t
时间戳。(您不需要那部分,而是使用您的桌子。)ts
bandwidth
这是一个非常相似的问题的非常相似的解决方案 - 详细解释了这个特定聚合是如何工作的:
以下是关于运行总和的类似问题的类似解决方案- 详细说明和使用的各种函数的链接:
WITH -- same as above ...
SELECT DISTINCT ON (1,2)
date_trunc('hour', ts) AS hour_stump
,(extract(minute FROM ts)::int / 15) AS min15_slot
,bandwidth AS bandwith_sample_at_min15
FROM t
WHERE ts >= '2012-09-02 00:00:00+02'::timestamptz
AND ts < '2012-09-03 00:00:00+02'::timestamptz
ORDER BY 1, 2, ts DESC;
每 15 分钟间隔检索一个未聚合的样本 - 从窗口中的最后一个可用行。如果该行没有丢失,这将是第 15 分钟。关键部分是DISTINCT ON
和ORDER BY
。
有关此处使用的技术的更多信息:
select
date_trunc('hour', d) +
(((extract(minute from d)::integer / 5 * 5)::text) || ' minute')::interval
as "from",
date_trunc('hour', d) +
((((extract(minute from d)::integer / 5 + 1) * 5)::text) || ' minute')::interval
- '1 second'::interval
as "to",
sum(random() * 1000) as bandwidth
from
generate_series('2012-01-01', '2012-01-31', '1 minute'::interval) s(d)
group by 1, 2
order by 1, 2
;
5分钟的范围。15 分钟除以 15。