sql - 如何创建一个有效的查询来按特定时间间隔计算记录?

标签 sql postgresql aggregate-functions window-functions generate-series

我使用哪个数据库?

我使用的是 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. 时间间隔取决于用户的选择。它可以是 1 秒37 秒50 分钟 或一些组合:2 个月零 30 分钟。时间间隔的可用单位:毫秒分钟小时月份年份。如您所见,我需要针对那个但是的一些通用/通用查询,我也可以为每个单元创建多个查询 - 这不是问题。
  2. 查询应该是高效的,因为我在一个大型数据库中工作(2000 万行或更多,但在查询中我只使用该数据库的一部分,例如:100 万)。

问题是:查询应该如何实现?

我试图转换我在以下线程中找到的解决方案,但我没有成功:

我有什么?

为了提高帖子的透明度,我删除了帖子的这一部分。本节不是回答我的问题所必需的。如果您想查看这里的内容,请查看该帖子的历史记录。

最佳答案

您的查询似乎很复杂。您只需要生成时间序列,然后使用 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/

相关文章:

连接3个表时MySQL查询错误

sql - PostgreSQL 窗口函数 : row_number() over (partition col order by col2)

postgresql - 通过 ADF 从 PostgreSQL 检索数据时,希腊字符集导致问题

ruby-on-rails - 你可以在 rails 中使用 find_each 进行分组吗?

sql - PostgreSQL HAVING 子句

mysql - SQL 仅选择列上具有最大值的行

mysql - 更改现有表中的列定义

SQL - 时间序列 - 对于缺失值返回 0

mysql - 关于MySql ID列的建议 - Rails

mysql - SQL 中总和的差异