按小时分组,合计平均

时间:2017-11-03 02:13:04

标签: sql postgresql group-by aggregate

我有一个包含工作历史的PostgreSQL表:

CREATE TABLE jobHistory
(
   jobid int4,
   starttime timestamptz,
   endtime timestamptz
);

我正在尝试创建一个SQL查询,以便每小时显示正在运行的作业的平均数。应该有24行(24小时为0-23),以包含该小时运行的平均作业数。

jobHistory表中的总行数约为20k。这是一个示例:

jobid  startTime                 endTime
------------------------------------------------------
377    2017-11-02 15:43:43.0     2017-11-02 15:49:22.0
114    2017-11-02 15:47:05.0     2017-11-02 15:56:19.0
378    2017-11-02 15:49:22.0     2017-11-02 15:53:01.0
379    2017-11-02 15:53:01.0     2017-11-02 16:33:16.0
380    2017-11-02 16:33:16.0     2017-11-02 16:51:26.0
381    2017-11-02 16:51:26.0     2017-11-02 17:03:00.0
382    2017-11-02 17:03:00.0     2017-11-02 17:11:59.0
383    2017-11-02 17:11:59.0     2017-11-02 17:12:44.0
384    2017-11-02 17:12:43.0     2017-11-02 17:13:36.0
385    2017-11-02 17:13:36.0     2017-11-02 17:14:20.0
386    2017-11-02 17:14:20.0     2017-11-02 17:15:08.0
387    2017-11-02 17:15:08.0     2017-11-02 17:16:03.0
388    2017-11-02 17:16:03.0     2017-11-02 18:31:01.0
150    2017-11-02 17:55:00.0     2017-11-02 18:16:32.0
153    2017-11-02 17:55:00.0     2017-11-02 18:15:28.0
135    2017-11-02 17:55:00.0     2017-11-02 17:55:01.0
132    2017-11-02 17:55:00.0     2017-11-02 18:13:00.0
156    2017-11-02 17:55:00.0     2017-11-02 17:55:06.0
147    2017-11-02 17:55:00.0     2017-11-02 17:57:47.0
138    2017-11-02 17:55:00.0     2017-11-02 18:12:33.0
140    2017-11-02 17:55:00.0     2017-11-02 17:55:17.0
389    2017-11-02 18:31:01.0     2017-11-02 18:38:11.0
390    2017-11-02 18:38:11.0     2017-11-02 18:38:35.0
391    2017-11-02 18:38:35.0     2017-11-02 18:38:39.0

我正在寻找每小时的平均工作数。乔布斯全天24小时都在运营。有些时间比其他人有更多的工作。总共大约有120个工作岗位。有些需要几分钟,有些需要几个小时为了保持负载平衡,当我安排一份新工作时,我想看看哪个小时的工作平均数最少。

2 个答案:

答案 0 :(得分:2)

你的问题不明确。

我假设您在total number of running jobs per hour列的基础上寻找starttime,以下是查询。

SELECT count(jobid) AS TotalJobs,
       date_trunc('hour', starttime) AS Date_Hour
FROM jobHistory
GROUP BY date_trunc('hour', starttime)
order by Date_Hour;

如果您需要endTime,则可以更改上述查询,将starttime替换为endTime

<强>结果:

totaljobs   date_hour
-------------------------------
4           02.11.2017 15:00:00
2           02.11.2017 16:00:00
15          02.11.2017 17:00:00
3           02.11.2017 18:00:00

希望这会有所帮助

<强> DEMO

答案 1 :(得分:0)

感谢所有看过这个的人。我确信有一种方法可以使用纯SQL获得答案,但我无法弄明白。为了回答我的问题,我编写了一个perl脚本来获得结果。

这是它的工作原理。

1.。)获取最早的工作记录和最新的工作记录之间的天数,这将用于平均每小时0-23的每次工作的工作数。
2.)对于每个作业记录,增加作业运行当天每小时的计数器。例如,如果作业从下午2点到下午6点运行,则脚本将增加2,3,4,5和6小时的计数器。如果作业超过23小时,我只需将值增加0-23。此时,我的结果有2列。第一列是小时(0-23),第二列是在该小时内运行的作业的出现次数 3.)然后我的脚本从上面的步骤2中取出数字,并将其除以产生平均值的天数。

因为我已经编写了一个perl脚本来生成结果,所以我现在知道安排新工作的最佳时间段是上午11点。

如果有人对解决SQL感兴趣,我会对看看它是如何完成感兴趣。现在,我只是保持我的perl脚本方便。

以下是完整工作历史数据的链接:

https://www.dropbox.com/s/bi66s0thh4sfp46/JobHistoryData.csv?dl=0

这是我的perl脚本的输出,它计算每小时的平均运行作业数:

0 = 2.49
1 = 2.10
2 = 2.16
3 = 2.02
4 = 4.10
5 = 2.86
6 = 2.00
7 = 1.69
8 = 1.69
9 = 1.80
10 = 1.67
11 = 1.53
12 = 1.76
13 = 1.73
14 = 8.33
15 = 2.24
16 = 1.63
17 = 8.67
18 = 6.12
19 = 5.00
20 = 4.84
21 = 3.76
22 = 10.43
23 = 4.37