按时间段分组并计算分组内某个字段平均值与求和

时间:2021-07-19 15:12:22

前段时间公司一个哥们为了偷懒,不愿意用程序去处理统计信息,让我写一个按照时间段分组并计算分组内某个字段平均值与求和,一开始我没怎么注意,觉得很简单,就答应帮他写,没想到写的时候无从下手,于是在网上找了一堆关于按照不同粒度在一段时间内分组解决办法,有的说要自己定义函数,看了他写的代码,一眼扫过去,就懵逼了,完全看不懂,搞得我都怀疑人生了,是不是自己不是程序员啊,怀疑人生的同时还得继续找啊,没办法,答应人家的事我得办到啊,于是继续找,找了大概一段时间,期间看到复杂的,直接pass,终于功夫不负有心人,找到一个代码比较少的,仔细看了一下,感觉完全符合我的需求,根本不需要自定义函数,于是试了一下自己所用的表,居然实现了同事向我描述的功能,瞬间感觉这他妈so easy。现在总结一下,connect by 这个语法很强大,贴上代码:

select d.p,t.crossing_no,count(t.crossing_no) from (select to_date('2018-06-22 19:00:00','yyyy-mm-dd hh24:mi:ss')-(level-1)*(5/60/24) p from dual connect by level<=(to_date('2018-06-22 19:00:00','yyyy-mm-dd hh24:mi:ss')-(to_date('2018-06-22 00:00:00','yyyy-mm-dd hh24:mi:ss')))*24*60/5+1) d left join t_detector_statis t
on t.start_time>d.p-5/60/24 and t.start_time<d.p
group by d.p,t.crossing_no
order by d.p desc

1.首先根据你传入的起止时间利用connect by level 这个语法算出需要分组的时间段

select to_date('2018-06-22 19:00:00','yyyy-mm-dd hh24:mi:ss')-(level-1)*(5/60/24) p from dual connect by level<=(to_date('2018-06-22 19:00:00','yyyy-mm-dd hh24:mi:ss')-(to_date('2018-06-22 00:00:00','yyyy-mm-dd hh24:mi:ss')))*24*60/5+1

(to_date('2018-06-22 19:00:00','yyyy-mm-dd hh24:mi:ss')-(to_date('2018-06-22 00:00:00','yyyy-mm-dd hh24:mi:ss')))*24*60/5+1这个计算出按照5分钟粒度划分多少段,即level最大值

to_date('2018-06-22 19:00:00','yyyy-mm-dd hh24:mi:ss')-(level-1)*(5/60/24)这个是根据level循环计算出时间段值

2.然后将分组后的时间段与你的业务逻辑表左连接

3.将左连接的结果,根据时间段分组,然后在组内进行分组函数计算。