1

我正在为这个项目使用 Postgress 数据库,但这个问题可以应用于任何数据库。

我需要更有效地从数据库中选择记录。我有一个表 Activity 包含在系统上注册的每个活动的记录。

表 Activity 由以下列组成

id             integer 
time_stamp     time stamp without timezone
computer_id    varchar(255)
user_id        varchar(255)
...

一般来说,我需要一个简单的结果。我需要能够指定 5 分钟或任何其他时间段的时间片。并且需要找出每个时间片中是否有记录。所以最后我需要每个时间片的 True 或 False 结果。

如果有 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 秒内。

4

1 回答 1

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

于 2013-10-17T17:11:14.313 回答