我使用哪个数据库?
我使用的是 PostgreSQL 9.5。
我需要什么?
这是我的 data_store
表的一部分:
id | starttime
-----+----------------------------
185 | 2011-09-12 15:24:03.248+02
189 | 2011-09-12 15:24:03.256+02
312 | 2011-09-12 15:24:06.112+02
313 | 2011-09-12 15:24:06.119+02
450 | 2011-09-12 15:24:09.196+02
451 | 2011-09-12 15:24:09.203+02
452 | 2011-09-12 15:24:09.21+02
... | ...
我想创建一个查询,该查询将按特定时间间隔对记录进行计数。例如,对于 4 秒的时间间隔 - 查询应该像这样返回给我:
starttime-from | starttime-to | count
---------------------+---------------------+---------
2011-09-12 15:24:03 | 2011-09-12 15:24:07 | 4
2011-09-12 15:24:07 | 2011-09-12 15:24:11 | 3
2011-09-12 15:24:11 | 2011-09-12 15:24:15 | 0
... | ... | ...
最重要的事情:
- 时间间隔取决于用户的选择。它可以是
1 秒
、37 秒
、50 分钟
或一些组合:2 个月零 30 分钟
。时间间隔的可用单位:毫秒
、秒
、分钟
、小时
、天
,月份
,年份
。如您所见,我需要针对那个但是的一些通用/通用查询,我也可以为每个单元创建多个查询 - 这不是问题。 - 查询应该是高效的,因为我在一个大型数据库中工作(2000 万行或更多,但在查询中我只使用该数据库的一部分,例如:100 万)。
问题是:查询应该如何实现?
我试图转换我在以下线程中找到的解决方案,但我没有成功:
- PostgreSQL: running count of rows for a query 'by minute' ,
- Group by data intervals ,
- Best way to count records by arbitrary time intervals in Rails+Postgres .
我有什么?
为了提高帖子的透明度,我删除了帖子的这一部分。本节不是回答我的问题所必需的。如果您想查看这里的内容,请查看该帖子的历史记录。
最佳答案
您的查询似乎很复杂。您只需要生成时间序列,然后使用 left join
将它们组合在一起即可。 . .和聚合:
select g.ts, g.ts + interval '4 second', count(ds.id)
from (select generate_series(min(starttime), max(strttime), interval '4 second') as ts
from data_store
) g left join
data_store ds
on ds.starttime >= g.ts and ds.starttime < g.ts + interval '4 second'
group by g.ts
order by g.ts;
注意:如果您希望间隔从精确的一秒开始(并且没有 1000 次中的 999 次奇怪的毫秒数),请使用 date_trunc()
。
编辑:
可能值得看看相关子查询是否更快:
select gs.ts,
(select count(*)
from data_store ds
where ds.starttime >= g.ts and ds.starttime < g.ts + interval '4 second'
) as cnt
from (select generate_series(min(starttime), max(strttime), interval '4 second') as ts
from data_store
) g;
关于sql - 如何创建一个有效的查询来按特定时间间隔计算记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38795316/