我正在尝试查找某个日期范围的平均开始时间,但平均功能似乎无法正常使用to_char(cast(Start_Dt as date),'HH24:MI')(Start_Dt sample:)12/12/18 02:30:13。关于如何获得理想结果的任何想法?
样品:
SELECT
job_nm
avg(to_char(cast(Start_Dt as date),'HH24:MI'))
FROM batch_table
Where Start_Dt >= trunc(sysdate-10)
group by job_nm
Run Code Online (Sandbox Code Playgroud)
错误:ORA-01722:无效号码01722。00000-“无效号码” *原因:指定的号码无效。*操作:指定一个有效数字。
理想的结果是查询仅查看最近10天运行的作业以及该期间的平均开始时间。
预期结果:
JOB_NM | AVG Time
open | 2:30
close | 3:30
Run Code Online (Sandbox Code Playgroud)
要计算平均时间,您可以使用:
SELECT
job_nm,
TO_CHAR(
TO_DATE(
AVG(
TO_NUMBER(
TO_CHAR(
TO_DATE(
TO_CHAR(Start_Dt,'HH24:MI:SS'),
'HH24:MI:SS'),
'sssss')
)
),
'sssss'),
'hh24:mi:ss')
FROM batch_table
WHERE Start_Dt >= trunc(sysdate-10)
GROUP BY job_nm;
Run Code Online (Sandbox Code Playgroud)
这是另一种选择,可能不太复杂:
SELECT
job_nm,
FLOOR(24 * AVG(Start_Dt- TRUNC(Start_Dt)))
|| ':'
|| FLOOR(MOD(24 * AVG(Start_Dt - TRUNC(Start_Dt)),1) * 60)
|| ':'
|| FLOOR(MOD(MOD(24 * AVG(Start_Dt- TRUNC(Start_Dt)),1) * 60,1) * 60)
FROM batch_table
WHERE Start_Dt >= trunc(sysdate-10)
GROUP BY job_nm;
Run Code Online (Sandbox Code Playgroud)
而且,以防万一,如果您要计算平均日期,可以将日期转换为儒略日期格式,计算平均值,然后转换回日期,例如:
SELECT
job_nm,
TO_DATE(
ROUND(
AVG(
TO_NUMBER(TO_CHAR(Start_Dt, 'J'))
)
),
'J')
FROM batch_table
WHERE Start_Dt >= trunc(sysdate-10)
GROUP BY job_nm;
Run Code Online (Sandbox Code Playgroud)
在将日期视为浮点数时,Oracle 非常灵活,因此可能不需要在接受的答案中进行大量复杂的数据类型转换:
SELECT
job_nm,
to_char(trunc(sysdate) + avg(start_dt - trunc(start_dt)),'HH24:MI')) avg_time
FROM batch_table
Where Start_Dt >= trunc(sysdate-10)
group by job_nm
Run Code Online (Sandbox Code Playgroud)
它有效是因为start_dt - trunc(start_dt)0 和 1 之间的浮点数代表一天中的时间(0.5 = 中午 12 点,0.75 = 6 点),这些都可以平均给出另一个浮点数,即平均时间(早上 6 点和下午 6 点是平均时间,中午 0.25 和0.75 是平均 0.5)。
将此添加回任何日期(如 trunc(sysdate))给出日期和时间,而 to_char 只是打印它的时间部分,将日期扔掉。Oracle 应该足够聪明,不会坚持按 trunc(sysdate) 分组
https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=2563874ab5566f9ff6030601497b718b