我正在使用这个项目的Postgress数据库,但这个问题可以应用于任何数据库。
我需要更有效地从数据库中选择记录。 我有一个表Activity,其中包含在系统上注册的每个活动的记录。
表Activity包含以下列
id integer
time_stamp time stamp without timezone
computer_id varchar(255)
user_id varchar(255)
...
一般来说,我需要一个简单的结果。 我需要能够指定5分钟或任何其他时间段的时间片。 并且需要找出每个时间片中是否有任何记录。所以最后我需要每个时间片都有一个真或假的结果。
如果存在True,我需要使用颜色为表格着色,或者为False将其留空。
我制作了一个程序解决方案,通过do while循环并为每个时间片选择一些记录。
例如:
select *
from Activity
where time_stamp between prev_Time and curr_Time
这有效,但速度很慢。如果时间片是5分钟,则有24小时x 60分钟/ 5分钟= 288个选择查询。
我需要找到一种方法来进行一次快速选择查询。我无法制作存储过程。 甚至更好的是不知道如何用SQL编写给我从开始时间到结束时间的所有时间段,以5分钟为一组。
即使在代码中的任何解决方案都是可以接受的,但必须快速。响应必须最多10秒钟。
答案 0 :(得分:1)
您可以使用generate_series()函数创建间隔,如下所示:
select g, count(a.id)
from generate_series(
'20131017 07:00'::timestamp,
'20131017 08:00'::timestamp,
'5 minutes'::interval
) as g
left outer join Activity as a on
a.time_stamp >= g and a.time_stamp < g + '5 minutes'::interval
group by g
order by g
如果您不需要记录count = 0的记录,则可以使用此查询:
with cte as (
select
(extract(epoch from time_stamp - '20131017 07:00'::timestamp) / 60)::int / 5 as p
from Activity
where time_stamp <= '20131017 08:00'::timestamp
)
select
'20131017 07:00'::timestamp + ((p * 5)::text || ' minutes')::interval, count(*)
from cte
group by p
<强> sql fiddle demo 强>