Oracle 两个日期字段之间的平均差异
Oracle average difference between two date fields
我在数据库中有一个 table 是这样的:
unit arrival_date departure_date
---- ------------- --------------
1 27/1/2017 08:01:20 a. m. 27/1/2017 08:04:27 a. m.
1 27/1/2017 08:05:35 a. m. 27/1/2017 08:09:28 a. m.
我需要计算用户 arrival_date 和 departure_date 之间的平均时间差,并将结果显示为时、分、秒格式 (HH:MI:SS)。
如果我这样做 arrival_date - departure_date
,我会在几天内得到结果,但我很难得到小时、分钟和秒的平均值。
这些字段是 DATE
个字段而不是 TIMESTAMP
个字段。
select unit, avg(departure_date - arrival_date) as avg_date
from mytable
这是一个例子。
当减去两个日期数据类型值时,结果是天数。它显示 INTER
CTE。当您将它乘以 24(一天中的小时数)、60(一小时中的分钟数)和 60(一分钟中的秒数)时,结果是秒数 (DIFF_SECS
)。
AVERAGES
CTE 展示了如何将 AVG
函数应用于以前的结果;没有什么 特别,只是注意你必须 GROUP
它 BY
UNIT
列。
最后,将 TO_CHAR
格式应用于计算(一些 TRUNC
和 MOD
调用是为了从 AVG_DIFF_SECS
值中提取小时、分钟和秒)。
我建议你 运行 每个 CTE 分开,一步一步,更容易跟随执行。
SQL> with test (unit, arr, dep) as
2 (select 1, to_date('27.01.2017 08:01:20', 'dd.mm.yyyy hh24:mi:ss'),
3 to_date('27.01.2017 08:04:27', 'dd.mm.yyyy hh24:Mi:ss')
4 from dual union all
5 select 1, to_date('27.01.2017 08:05:35', 'dd.mm.yyyy hh24:mi:ss'),
6 to_date('27.01.2017 08:09:28', 'dd.mm.yyyy hh24:Mi:ss')
7 from dual
8 ),
9 inter as
10 (select unit, (dep - arr) diff_days,
11 (dep - arr) * 24 * 60 * 60 diff_secs
12 from test
13 ),
14 averages as
15 (select unit,
16 avg(dep - arr) avg_diff_days,
17 avg((dep - arr) * 24 * 60 * 60) avg_diff_secs
18 from test
19 group by unit
20 )
21 select
22 to_char(trunc(avg_diff_secs / 3600), 'fm00') || ':' || -- hours
23 to_char(trunc(mod(avg_diff_secs , 3600) / 60), 'fm00') || ':' || -- minutes
24 to_char(mod(avg_diff_secs, 60), 'fm00') -- seconds
25 avg_diff_formatted
26 from averages;
AVG_DIFF_FORMATTED
--------------------
00:03:30
SQL>
我在数据库中有一个 table 是这样的:
unit arrival_date departure_date
---- ------------- --------------
1 27/1/2017 08:01:20 a. m. 27/1/2017 08:04:27 a. m.
1 27/1/2017 08:05:35 a. m. 27/1/2017 08:09:28 a. m.
我需要计算用户 arrival_date 和 departure_date 之间的平均时间差,并将结果显示为时、分、秒格式 (HH:MI:SS)。
如果我这样做 arrival_date - departure_date
,我会在几天内得到结果,但我很难得到小时、分钟和秒的平均值。
这些字段是 DATE
个字段而不是 TIMESTAMP
个字段。
select unit, avg(departure_date - arrival_date) as avg_date
from mytable
这是一个例子。
当减去两个日期数据类型值时,结果是天数。它显示 INTER
CTE。当您将它乘以 24(一天中的小时数)、60(一小时中的分钟数)和 60(一分钟中的秒数)时,结果是秒数 (DIFF_SECS
)。
AVERAGES
CTE 展示了如何将 AVG
函数应用于以前的结果;没有什么 特别,只是注意你必须 GROUP
它 BY
UNIT
列。
最后,将 TO_CHAR
格式应用于计算(一些 TRUNC
和 MOD
调用是为了从 AVG_DIFF_SECS
值中提取小时、分钟和秒)。
我建议你 运行 每个 CTE 分开,一步一步,更容易跟随执行。
SQL> with test (unit, arr, dep) as
2 (select 1, to_date('27.01.2017 08:01:20', 'dd.mm.yyyy hh24:mi:ss'),
3 to_date('27.01.2017 08:04:27', 'dd.mm.yyyy hh24:Mi:ss')
4 from dual union all
5 select 1, to_date('27.01.2017 08:05:35', 'dd.mm.yyyy hh24:mi:ss'),
6 to_date('27.01.2017 08:09:28', 'dd.mm.yyyy hh24:Mi:ss')
7 from dual
8 ),
9 inter as
10 (select unit, (dep - arr) diff_days,
11 (dep - arr) * 24 * 60 * 60 diff_secs
12 from test
13 ),
14 averages as
15 (select unit,
16 avg(dep - arr) avg_diff_days,
17 avg((dep - arr) * 24 * 60 * 60) avg_diff_secs
18 from test
19 group by unit
20 )
21 select
22 to_char(trunc(avg_diff_secs / 3600), 'fm00') || ':' || -- hours
23 to_char(trunc(mod(avg_diff_secs , 3600) / 60), 'fm00') || ':' || -- minutes
24 to_char(mod(avg_diff_secs, 60), 'fm00') -- seconds
25 avg_diff_formatted
26 from averages;
AVG_DIFF_FORMATTED
--------------------
00:03:30
SQL>