对数据库表按时间进行5分钟分组统计(oracle)
案例中提到几个函数:
to_char(待转换参数,格式):格式转换
可将date类型或字符串日期转换为需要的格式
to_date(待转换参数,格式):日期格式转换
可将字符串日期转换为date类型的格式
lpad(待补全字符串,长度,需补字符):字符补全
从左边对字符串进行指定长度,指定补全内容
floor(X):小于或等于X的最大值
案例:将某表中的数据按时间每5分钟进行分组统计数量,数据表中时间是时间戳的格式,所以,先将数据表中的时间转换为字符串格式的日期,再对结果集进行分组统计
SELECT vehClass,
to_char(TO_DATE(TIME, 'yyyy-MM-dd hh24:mi:ss'),'yyyy-MM-dd hh24')||':'||lpad(floor(to_char(TO_DATE(TIME, 'yyyy-MM-dd HH24:mi:ss'),'mi')/5)*5,2,0) AS STAT_TIME,
SZ_SOURCE_CODE,COUNT(*) FROM (
SELECT sdd.DICT_LABEL AS vehClass,TO_CHAR(UBI_TIME / (1000 * 60 * 60 * 24) +
TO_DATE('1970-01-01 08:00:00', 'yyyy-MM-dd HH24:mi:ss'), 'yyyy-MM-dd HH24:mi:ss') as time,SZ_SOURCE_CODE FROM TBL_EVENT_PLATE_INFO pvi
JOIN SYS_DICT_DATA sdd ON sdd.DICT_VALUE = pvi.UI_STAT_TYPE AND sdd.DICT_TYPE = 'veh_class'
WHERE
TO_CHAR(UBI_TIME / (1000 * 60 * 60 * 24) +
TO_DATE('1970-01-01 08:00:00', 'yyyy-MM-dd HH24:mi:ss'), 'yyyy-MM-dd HH24:mi:ss') BETWEEN to_char(to_date('2023-09-04 00:00:00','yyyy-MM-dd HH24:mi:ss'),'yyyy-MM-dd HH24:mi:ss') AND to_char(to_date('2023-09-10 23:59:59','yyyy-MM-dd HH24:mi:ss'),'yyyy-MM-dd HH24:mi:ss')
AND SZ_SOURCE_CODE =201)
GROUP BY vehClass,to_char(TO_DATE(TIME, 'yyyy-MM-dd hh24:mi:ss'),'yyyy-MM-dd hh24')||':'||lpad(floor(to_char(TO_DATE(TIME, 'yyyy-MM-dd HH24:mi:ss'),'mi')/5)*5,2,0),SZ_SOURCE_CODE
ORDER BY vehClass,to_char(TO_DATE(TIME, 'yyyy-MM-dd hh24:mi:ss'),'yyyy-MM-dd hh24')||':'||lpad(floor(to_char(TO_DATE(TIME, 'yyyy-MM-dd HH24:mi:ss'),'mi')/5)*5,2,0),SZ_SOURCE_CODE
结果:
存在的问题:无数据的时间段没有补0
解决方法:
可取需要统计的时间段内的所有每隔5分钟的时间,再与上述语句的结果集进行按时间点left join为一个结果集,然后再进行nvl补零
参考语句(可自行改写为取每5分钟时间)
SELECT to_char(TO_DATE(SUBSTR('2023-09-04 00:00:00', 1, 16), 'YYYY-MM-DD HH24:MI') + (ROWNUM-1 ) / (24 * 60) ,'yyyy-mm-dd HH24:MI') AS DATES FROM DUAL
CONNECT BY ROWNUM <= floor(to_number(TO_DATE(SUBSTR('2023-09-10 23:59:59', 1, 16), 'yyyy-mm-dd HH24:MI')-to_date(SUBSTR('2023-09-04 00:00:00', 1, 16),
'yyyy-mm-dd hh24:MI'))*(24 * 60) +1)