为15分钟windows选择数据-PostgreSQL

为15分钟windows选择数据-PostgreSQL,postgresql,histogram,window-functions,Postgresql,Histogram,Window Functions,好的,我在PostgreSQL中有这样一个表: timestamp duration 2013-04-03 15:44:58 4 2013-04-03 15:56:12 2 2013-04-03 16:13:17 9 2013-04-03 16:16:30 3 2013-04-03 16:29:52 1 2013-04-03 16:38:25 1 2013-04-03 16:41:37 9 2013-04-03 16:44:4

好的,我在PostgreSQL中有这样一个表:

timestamp              duration

2013-04-03 15:44:58    4
2013-04-03 15:56:12    2
2013-04-03 16:13:17    9
2013-04-03 16:16:30    3
2013-04-03 16:29:52    1
2013-04-03 16:38:25    1
2013-04-03 16:41:37    9
2013-04-03 16:44:49    1
2013-04-03 17:01:07    9
2013-04-03 17:07:48    1
2013-04-03 17:11:00    2
2013-04-03 17:11:16    2
2013-04-03 17:15:17    1
2013-04-03 17:16:53    4
2013-04-03 17:20:37    9
2013-04-03 17:20:53    3
2013-04-03 17:25:48    3
2013-04-03 17:29:26    1
2013-04-03 17:32:38    9
2013-04-03 17:36:55    4
我希望得到以下输出:

TimestampWindowsStart=2013-04-0315:44:58

duration    count
1           0
2           1
3           0
4           1
9           0
timestampwindowstart=2013-04-03 15:59:58

duration    count
1           0
2           0
3           0
4           0
9           1
timestampwindowstart=2013-04-03 16:14:58

duration    count
1           1
2           0
3           1
4           0
9           0
timestampwindowstart=2013-04-03 16:29:58

duration    count
1           2
2           0
3           0
4           0
9           1
等等

因此,基本上,它在15分钟窗口中循环时间戳,并输出不同的持续时间值及其频率(计数)。TimestampWindowsStart值是窗口的最早时间戳(即timestampwindowfinish=TimestampWindowsStart+15分钟)

这样我就可以画出15分钟的间隔直方图

我已经试过阅读了,但是我的头脑有点复杂,我没有太多的时间

谢谢你的帮助

快速肮脏的方式:我将我的专栏命名为
tstamp
,而不是您的
时间戳

with t as (
  select
    generate_series(mitstamp,matstamp,'15 minutes') as int,
    duration
  from
    (select min(tstamp) mitstamp, max(tstamp) as matstamp from tmp) a,
    (select duration from tmp group by duration) b
)

select
  int as timestampwindowstart,
  t.duration,
  count(tmp.duration)
from
   t
   left join tmp on 
         (tmp.tstamp >= t.int and 
          tmp.tstamp < (t.int + interval '15 minutes') and 
          t.duration = tmp.duration)
group by
  int,
  t.duration
order by
  int,
  t.duration

您应该真正了解PostgreSQL中的
with
子句。这对于PostgreSQL中的任何数据分析都是非常宝贵的概念。

好的,您没有时间,但希望其他人投入宝贵的时间来解决您的问题。你至少可以用你的数据创建一个SQLfiddle。我说我没有太多的时间了,我已经花了很长时间试图解决这个问题,我不能。。。至于SQLfiddle演示,并不是每个人都使用SQLfiddle,只有少数人帮助过我使用SQLfiddle演示,所以我没有想到要创建一个,我现在就创建一个,非常感谢,你能解释一下代码吗?我目前正在运行查询,一旦查询完成,我将接受此答案。按照我的理解,您可以创建一个临时表,其中包含一个时间戳序列,该时间戳序列是通过将15分钟的间隔添加到最小时间戳、最大时间戳以及按不同持续时间分组的持续时间而生成的。然后选择时间戳间隔,持续时间和持续时间频率,通过执行到临时表的联接,并根据时间戳间隔和持续时间进行分组和排序…也很抱歉添加到原始问题中,但是如果我有三个表都具有相同的格式,并且我希望做相同的事情,但使用所有三个表中的数据,我将如何修改此代码表格?twn08共享的答案不使用临时表格,而是使用CTE(通用表格表达式),可在文档的部分中找到。如果您想使用三个表,您可能会将它们合并在一起,请参阅感谢您的回复,我认为使用联合的方式是将整个查询与第二个表上的同一个查询合并,但是15分钟的间隔不会弄乱吗?对于每个表,最后一个间隔将在最后一个时间戳处停止,而不是继续到第二个表的第一个时间戳?谢谢你让我知道CTE的事!“快”…?;)
with 

tmpout as (
  select * from tmp1 union all
  select * from tmp2 union all
  select * from tmp3
)

,t as (
  select
    generate_series(mitstamp,matstamp,'15 minutes') as int,
    duration
  from
    (select min(tstamp) mitstamp, max(tstamp) as matstamp from tmpout) a,
    (select duration from tmpout group by duration) b
)

select
  int as timestampwindowstart,
  t.duration,
  count(tmp.duration)
from
   t
   left join tmpout on 
         (tmp.tstamp >= t.int and 
          tmp.tstamp < (t.int + interval '15 minutes') and 
          t.duration = tmp.duration)
group by
  int,
  t.duration
order by
  int,
  t.duration