找到两组日期范围之间的重叠
find overlap between two sets of date ranges
我想使用 Oracle SQL 或 PL/SQL.
找出每个订单号的两组日期范围之间的重叠
输入是“结果集一”和“结果集二”。输出应该是“重叠”。
结果集一
WITH T_RESULT_SET_ONE as(
select 21365 order_number,to_date('01/01/2021 09:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 10:30:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21365 order_number,to_date('02/01/2021 14:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('02/01/2021 18:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 08:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:43:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 16:34:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 18:15:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21367 order_number,to_date('04/01/2021 15:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('04/01/2021 16:15:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
)
或
结果集二
T_RESULT_SET_TWO as(
select 21365 order_number,to_date('01/01/2021 09:30:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:45:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21365 order_number,to_date('02/01/2021 13:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('02/01/2021 17:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21367 order_number,to_date('01/01/2021 09:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 10:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 16:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 19:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('05/01/2021 19:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('04/01/2021 19:46:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
)
或
重叠
T_OVERLAP as
(
select 21365 order_number,to_date('01/01/2021 09:30:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:45:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21365 order_number,to_date('02/01/2021 14:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('02/01/2021 17:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21367 order_number,to_date('01/01/2021 09:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:43:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 16:34:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 18:15:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
)
或
下图说明了我要执行的操作(日期范围与我之前提供的不一样)
任何人都可以提供 SQL 查询或 PL/SQL 程序吗?
看来你要找的不是INTERSECT而是重叠的。在Oracle中intersect一般指2个查询的共同结果:
Select <columns list> from table1
INTERSECT
Select <columns list> from table2;
其中列列表具有相同的定义并且结果值相同。您正在寻找的是值彼此重叠的位置,而不是行包含相同值的位置。
让我们考虑 2 个事件调用 'A' 和 'B',重叠的可能性有 4 种:
- A开始,B开始,B结束,A结束。 A完全重叠B.
- A开始,B开始,A结束,B结束。 A 重叠 B
的开头
- B开始,A开始,B结束,A结束。 A 与 B
的结尾重叠
- B开始,A开始,A结束,B结束。 A与B完全重叠。
解析只是确定,就是需要确定我们取最大开始时间和最小结束时间的重叠。使用您提供的数据,这只需要上述其中一项:
select order_number
, greatest(t1start, t2start) start_date_time
, least(t1finish,t2finish) finish_date_time
from ( select t1.order_number
, t1.start_date_time t1start
, t1.finish_date_time t1finish
, t2.start_date_time t2start
, t2.finish_date_time t2finish
from t_result_set_one t1
join t_result_set_two t2
on t1.order_number = t2.order_number
where ( t1.finish_date_time >= t2.start_date_time
and t1.start_date_time <= t2.finish_date_time
)
);
参见fiddle here。我给你留下其他3种可能性。
我想使用 Oracle SQL 或 PL/SQL.
找出每个订单号的两组日期范围之间的重叠输入是“结果集一”和“结果集二”。输出应该是“重叠”。
结果集一
WITH T_RESULT_SET_ONE as(
select 21365 order_number,to_date('01/01/2021 09:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 10:30:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21365 order_number,to_date('02/01/2021 14:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('02/01/2021 18:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 08:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:43:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 16:34:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 18:15:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21367 order_number,to_date('04/01/2021 15:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('04/01/2021 16:15:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
)
或
结果集二
T_RESULT_SET_TWO as(
select 21365 order_number,to_date('01/01/2021 09:30:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:45:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21365 order_number,to_date('02/01/2021 13:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('02/01/2021 17:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21367 order_number,to_date('01/01/2021 09:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 10:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 16:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 19:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('05/01/2021 19:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('04/01/2021 19:46:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
)
或
重叠
T_OVERLAP as
(
select 21365 order_number,to_date('01/01/2021 09:30:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:45:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21365 order_number,to_date('02/01/2021 14:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('02/01/2021 17:00:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
union
select 21367 order_number,to_date('01/01/2021 09:00:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 09:43:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
UNION
select 21367 order_number,to_date('01/01/2021 16:34:00', 'DD/MM/YYYY HH24:MI:SS') start_date_time, to_date('01/01/2021 18:15:00', 'DD/MM/YYYY HH24:MI:SS') finish_date_time FROM DUAL
)
或
下图说明了我要执行的操作(日期范围与我之前提供的不一样)
任何人都可以提供 SQL 查询或 PL/SQL 程序吗?
看来你要找的不是INTERSECT而是重叠的。在Oracle中intersect一般指2个查询的共同结果:
Select <columns list> from table1
INTERSECT
Select <columns list> from table2;
其中列列表具有相同的定义并且结果值相同。您正在寻找的是值彼此重叠的位置,而不是行包含相同值的位置。
让我们考虑 2 个事件调用 'A' 和 'B',重叠的可能性有 4 种:
- A开始,B开始,B结束,A结束。 A完全重叠B.
- A开始,B开始,A结束,B结束。 A 重叠 B 的开头
- B开始,A开始,B结束,A结束。 A 与 B 的结尾重叠
- B开始,A开始,A结束,B结束。 A与B完全重叠。
解析只是确定,就是需要确定我们取最大开始时间和最小结束时间的重叠。使用您提供的数据,这只需要上述其中一项:
select order_number
, greatest(t1start, t2start) start_date_time
, least(t1finish,t2finish) finish_date_time
from ( select t1.order_number
, t1.start_date_time t1start
, t1.finish_date_time t1finish
, t2.start_date_time t2start
, t2.finish_date_time t2finish
from t_result_set_one t1
join t_result_set_two t2
on t1.order_number = t2.order_number
where ( t1.finish_date_time >= t2.start_date_time
and t1.start_date_time <= t2.finish_date_time
)
);
参见fiddle here。我给你留下其他3种可能性。