postgres工作日频率按小时计算

时间:2014-06-12 12:55:19

标签: postgresql

我想生成一个类似下面的报告(是Google Analytics App for Android的屏幕截图)

我的活动每天发生10-15次,我希望每个工作日都能看到从一开始就以小时为单位的频率。

我只需要使用名为“created_at”的DateTime(时间戳)字段(是一个Rails项目)

我怎样才能在PostgreSQL中做到这一点?

谢谢

sample output

2 个答案:

答案 0 :(得分:1)

这很容易。您只需按一天中的小时和当天的日期分组,然后计算,有多少元素。结果的前两列(日期和日期的小时)是图表中相应单元格的2D坐标。第三列(计数)为您提供该单元格的颜色。

一个例子:

SELECT 
   extract('hour' FROM starttime) as hour, 
   date_trunc('day', starttime) as day,
   count(*) as nbmr
FROM actions
GROUP BY hour, day;

Live fiddle

在此示例中,“hour”和“day”列对应于图表中单元格的y轴和x轴。然后,“nmbr”列会告诉您该单元格的颜色。

您可以轻松修改此查询,例如按工作日显示百分比和组(0表示星期日):

SELECT 
   extract('hour' FROM starttime) as hour, 
   extract('dow' FROM starttime) as day,
   count(*) * 100.0 / (select count(*) from actions) as nbmr
FROM actions
GROUP BY hour, day;

Live fiddle

答案 1 :(得分:1)

已经提供的答案都是正确的,但这里的变化只是使用“tablefunc”扩展来对结果进行交叉制表,以使其看起来与您的样本完全一致。

在使用它之前,你必须创建tablefunc扩展(在postgresql的contrib包中可用):

CREATE EXTENSION IF NOT EXISTS tablefunc;

这是查询,假设输入数据位于表t的<_p>列created_at中

SELECT * FROM CROSSTAB($$SELECT h.hour AS hour_of_day,
    dow.day AS day, 
    COUNT(t.created_at)::INT
FROM (values('Mon'),('Tue'),('Wed'),('Thu'),('Fri'),('Sat'),('Sun')) AS dow(day)
CROSS JOIN generate_series(0,23) as h(hour)
LEFT JOIN t ON to_char(t.created_at, 'Dy')=dow.day AND extract(hour from t.created_at)=h.hour
GROUP BY dow.day,h.hour
ORDER BY h.hour,dow.day$$) AS d(Hour int, "Mon" int,"Tue" int,"Wed" int,"Thu" int,"Fri" int,"Sat" int,"Sun" int);

需要注意的要点:

  • 查询交叉连接时间集与小时00-23的集合,以便即使输入表中没有给定单元格的数据,输出中的所有单元格也都存在
  • 交叉表函数将SQL查询作为输入并交叉制表结果,生成记录集
  • 由于我不完全清楚的原因,我必须从计数中转换返回值(我猜它会以BIGINT的形式返回?)
  • 您(遗憾的是)您必须通过AS子句拼写结果中的列名,如图所示

结果如下:

 hour | Mon | Tue | Wed | Thu | Fri | Sat | Sun
------+-----+-----+-----+-----+-----+-----+-----
    0 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    1 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    2 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    3 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    4 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    5 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    6 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    7 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    8 |   0 |   0 |   0 |   0 |   0 |   0 |   0
    9 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   10 |   0 |   0 |   0 |   0 |   0 |   0 |   1
   11 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   12 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   13 |   0 |   0 |   0 |   1 |   0 |   0 |   0
   14 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   15 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   16 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   17 |   0 |   0 |   1 |   0 |   0 |   0 |   0
   18 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   19 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   20 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   21 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   22 |   0 |   0 |   0 |   0 |   0 |   0 |   0
   23 |   0 |   0 |   0 |   0 |   1 |   0 |   0
(24 rows)

从此样本数据生成的内容:

         created_at
----------------------------
 2014-06-12 23:06:03.746884
 2014-01-15 10:00:00
 2014-05-25 13:00:00
 2014-03-01 17:00:00
(4 rows)