Oracle SQL - 如何计算两个日期之间的工作时间和分钟数
Oracle SQL - How to work out the working hours and minutes between two dates
Oracle SQL 有没有办法找出两个日期之间的工作小时数和分钟数?
举个例子
工作日为周一至周五上午 8 点至下午 5 点
Job.Job_Logged Job.Actual_Start_Date Time Elapsed
01/08/2019 10:00 01/08/2019 12:32 2:32
01/08/2019 16:00 02/08/2019 09:00 3:00
我没有检查可能的重复项,但一种方法是递归查询:
with cte(id, start_date, end_date, hd1, hd2) as (
select id, cast(start_date as date), cast(end_date as date), cast(start_date as date),
cast(least(end_date, trunc(start_date) + 17/24) as date)
from jobs
union all
select id, start_date, end_date, cast(trunc(hd1) + 1 + 8/24 as date),
cast(least(trunc(hd1) + 1 + 17/24, end_date) as date)
from cte
where trunc(hd1) + 1 + 8/24 < end_date)
select id, start_date, end_date, dbms_xplan.format_time_s(sum(hd2 - hd1) * 24 * 60) hours
from cte
where to_char(hd1, 'd') not in (6, 7)
group by id, start_date, end_date
我使用 17/24
的地方表示结束时间 17:00
,8/24
- 开始时间,not in (6, 7)
不包括周六和周日。
编辑1:最后应该是24 * 60 * 60 select.
编辑 2: 要使查询独立于 nls_settings 使用:
to_char(hd1, 'Dy', 'nls_date_language=english') not in ('Sat', 'Sun')
the version of Oracle I'm using insists on having SELECT as the first
word in any code
这种递归查询从Oracle version 11开始就有了。我不知道你的工具是否需要在第一行使用select
或者是这个版本的问题,但是在第一种情况下你可以将RCTE移动到from
子句:
select id, start_date, end_date, dbms_xplan.format_time_s(sum(hd2 - hd1) * 24 * 60 * 60) hours
from (
with
cte(id, start_date, end_date, hd1, hd2) as (
select id, cast(start_date as date), cast(end_date as date), cast(start_date as date),
cast(least(end_date, trunc(start_date) + 17/24) as date)
from jobs
union all
select id, start_date, end_date, cast(trunc(hd1) + 1 + 8/24 as date),
cast(least(trunc(hd1) + 1 + 17/24, end_date) as date)
from cte
where trunc(hd1) + 1 + 8/24 < end_date)
select * from cte
where to_char(hd1, 'Dy', 'nls_date_language=english') not in ('Sat', 'Sun') )
group by id, start_date, end_date
Oracle SQL 有没有办法找出两个日期之间的工作小时数和分钟数?
举个例子
工作日为周一至周五上午 8 点至下午 5 点
Job.Job_Logged Job.Actual_Start_Date Time Elapsed
01/08/2019 10:00 01/08/2019 12:32 2:32
01/08/2019 16:00 02/08/2019 09:00 3:00
我没有检查可能的重复项,但一种方法是递归查询:
with cte(id, start_date, end_date, hd1, hd2) as (
select id, cast(start_date as date), cast(end_date as date), cast(start_date as date),
cast(least(end_date, trunc(start_date) + 17/24) as date)
from jobs
union all
select id, start_date, end_date, cast(trunc(hd1) + 1 + 8/24 as date),
cast(least(trunc(hd1) + 1 + 17/24, end_date) as date)
from cte
where trunc(hd1) + 1 + 8/24 < end_date)
select id, start_date, end_date, dbms_xplan.format_time_s(sum(hd2 - hd1) * 24 * 60) hours
from cte
where to_char(hd1, 'd') not in (6, 7)
group by id, start_date, end_date
我使用 17/24
的地方表示结束时间 17:00
,8/24
- 开始时间,not in (6, 7)
不包括周六和周日。
编辑1:最后应该是24 * 60 * 60 select.
编辑 2: 要使查询独立于 nls_settings 使用:
to_char(hd1, 'Dy', 'nls_date_language=english') not in ('Sat', 'Sun')
the version of Oracle I'm using insists on having SELECT as the first word in any code
这种递归查询从Oracle version 11开始就有了。我不知道你的工具是否需要在第一行使用select
或者是这个版本的问题,但是在第一种情况下你可以将RCTE移动到from
子句:
select id, start_date, end_date, dbms_xplan.format_time_s(sum(hd2 - hd1) * 24 * 60 * 60) hours
from (
with
cte(id, start_date, end_date, hd1, hd2) as (
select id, cast(start_date as date), cast(end_date as date), cast(start_date as date),
cast(least(end_date, trunc(start_date) + 17/24) as date)
from jobs
union all
select id, start_date, end_date, cast(trunc(hd1) + 1 + 8/24 as date),
cast(least(trunc(hd1) + 1 + 17/24, end_date) as date)
from cte
where trunc(hd1) + 1 + 8/24 < end_date)
select * from cte
where to_char(hd1, 'Dy', 'nls_date_language=english') not in ('Sat', 'Sun') )
group by id, start_date, end_date