PL/SQL Split,根据黑色日期将一个日期分割成新的日期!
我有一个“旅行日期”和禁止日期。 我会根据限制日期将旅行日期分成几部分。
注意:旅行日期可以在 0 - 9999 99 99
示例:
Travel Date:
Travel | START DATE | END DATE
T | 2011 01 04 | 2011 12 11
Black Out Dates:
BO | START DATE | END DATE
A | 2010 11 01 | 2011 02 11
B | 2011 01 20 | 2011 02 15
C | 2011 03 13 | 2011 04 10
D | 2011 03 20 | 2011 06 29
例外结果:
New Travel | START DATE | END DATE
X1 | 2011 02 16 | 2011 03 12
X2 | 2011 06 30 | 2011 12 11
视觉上:
NAME : date range
Travel Date : -----[--------------------------]--
A : --[------]-------------------------
B : ------[---]------------------------
C : --------------[---]----------------
D : ----------------[------]-----------
结果:
X1 : -----------[--]--------------------
X2 : -----------------------[--------]--
示例 2:
Travel Date : -[--------------------------------]--
BO Date A : ----[------]-------------------------
BO Date B : ----------------------[------]-------
BO Date C : --------------------[---]------------
BO Date D : ------------------[------]-----------
Result X1 : -[--]--------------------------------
Result X2 : -----------[------]------------------
Result X3 : -----------------------------[----]--
示例 3:
Travel Date : ]-----------------------------------[
BO Date A : ----[------]-------------------------
BO Date B : -------------------------[---]-------
BO Date C : ----------------[---]----------------
BO Date D : ------------------[------]-----------
Result X1 : ---]---------------------------------
Result X2 : -----------[--]----------------------
Result X3 : -----------------------------[-------
如何使用 PL SQL 执行此操作?
谢谢。
以下是表格和测试用例:
DROP TABLE TRACES.TRAVEL CASCADE CONSTRAINTS;
CREATE TABLE TRACES.TRAVEL
(
START_DATE DATE,
END_DATE DATE
);
DROP TABLE TRACES.BLACK_OUT_DATES CASCADE CONSTRAINTS;
CREATE TABLE TRACES.BLACK_OUT_DATES
(
BO CHAR( 1 BYTE ),
START_DATE DATE,
END_DATE DATE
);
/*
TEST CASE 1
-------------------------------------------------------------------
Expected Results:
01/01/0001 09/02/2011
16/02/2011 01/04/2011
21/04/2011 10/05/2011
16/06/2011 19/11/2011
30/11/2011 31/12/9999
Visually:
Travel:
----------------------------------------------------
BO:
--[--]----------------------------------------------
---------------[------]-----------------------------
-----------------------------[---------------]------
Result:
[-]---[--------]-------[-----]----------------[-----]
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '0001-01-01', DATE '9999-12-31' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-10', DATE '2011-02-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-04-02', DATE '2011-04-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-05-11', DATE '2011-06-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-11-20', DATE '2011-11-29' );
--INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-05-09', DATE '2011-05-12' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 2
-------------------------------------------------------------------
Expected Results:
01/01/2011 01/02/2011
07/05/2011 06/07/2011
21/07/2011 31/12/2011
Visually:
Travel:
[------------------------------------------------------]
BO:
--[----------------------]------------------------------
---------------[--]-------------------------------------
---------------------------------[--------]-------------
----------------------------------------[--------]------
Result:
[--]---------------------[---------]--------------[----]
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-01-01', DATE '2011-12-31' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-02', DATE '2011-05-06' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-03-03', DATE '2011-03-05' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-07-07', DATE '2011-07-09' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-07-08', DATE '2011-07-20' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 3
-------------------------------------------------------------------
Expected Results:
04/05/2011 03/06/2011
21/06/2011 07/08/2011
Visually:
Travel:
[------------------------------------------------------]
BO:
--[----------------------]------------------------------
---------------[--]-------------------------------------
---------------------------------[--------]-------------
----------------------------------------[--------]------
Result:
[--]---------------------[---------]--------------[----]
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-04-02', DATE '2011-10-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-01-01', DATE '2011-05-03' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-06-04', DATE '2011-06-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-06-06', DATE '2011-06-08' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-08-08', DATE '2011-12-30' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-08-08', DATE '2011-12-30' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 4
-------------------------------------------------------------------
Expected Results:
21/02/2011 09/04/2011
26/04/2011 09/05/2011
Visually:
Travel:
----[-------------------------]-------------------------
BO:
--[----]------------------------------------------------
----[----]----------------------------------------------
-------------[--------]---------------------------------
------------------[--]----------------------------------
--------------------------[--------]--------------------
Result:
----------[--]--------[--]-----------------------------
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-02-10', DATE '2011-05-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-02', DATE '2011-02-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-02-10', DATE '2011-02-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-04-10', DATE '2011-04-25' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-04-15', DATE '2011-04-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-05-10', DATE '2011-05-20' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 5
-------------------------------------------------------------------
Expected Results:
21/02/2011 04/05/2011
Visually:
Travel:
------[-------------------------]-----------------------
BO:
-[-----]------------------------------------------------
--[--]--------------------------------------------------
----------------------------[--------]------------------
------------------------------[-----]-------------------
-------------------------------[--]---------------------
Result:
--------[-------------------]---------------------------
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-02-10', DATE '2011-05-17' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-05', DATE '2011-02-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-02-07', DATE '2011-02-09' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-05-05', DATE '2011-05-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-05-07', DATE '2011-05-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-05-09', DATE '2011-05-12' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 6
-------------------------------------------------------------------
Expected Results:
No Result
Visually:
Travel:
------[----------------------------]--------------------
BO:
--[---------------------------------------]-------------
Result:
No Result
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-02-10', DATE '2011-09-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-01-05', DATE '2011-10-10' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
I have lets say a "travel date" and black out dates.
I will split the travel date into pieces according to the black out dates.
Note: Travel Date can be between 0 - 9999 99 99
Sample:
Travel Date:
Travel | START DATE | END DATE
T | 2011 01 04 | 2011 12 11
Black Out Dates:
BO | START DATE | END DATE
A | 2010 11 01 | 2011 02 11
B | 2011 01 20 | 2011 02 15
C | 2011 03 13 | 2011 04 10
D | 2011 03 20 | 2011 06 29
Excepted Result:
New Travel | START DATE | END DATE
X1 | 2011 02 16 | 2011 03 12
X2 | 2011 06 30 | 2011 12 11
Visually:
NAME : date range
Travel Date : -----[--------------------------]--
A : --[------]-------------------------
B : ------[---]------------------------
C : --------------[---]----------------
D : ----------------[------]-----------
Result :
X1 : -----------[--]--------------------
X2 : -----------------------[--------]--
Sample 2:
Travel Date : -[--------------------------------]--
BO Date A : ----[------]-------------------------
BO Date B : ----------------------[------]-------
BO Date C : --------------------[---]------------
BO Date D : ------------------[------]-----------
Result X1 : -[--]--------------------------------
Result X2 : -----------[------]------------------
Result X3 : -----------------------------[----]--
Sample 3:
Travel Date : ]-----------------------------------[
BO Date A : ----[------]-------------------------
BO Date B : -------------------------[---]-------
BO Date C : ----------------[---]----------------
BO Date D : ------------------[------]-----------
Result X1 : ---]---------------------------------
Result X2 : -----------[--]----------------------
Result X3 : -----------------------------[-------
How can I do it using PL SQL ?
Thanks.
Here are the tables and test cases:
DROP TABLE TRACES.TRAVEL CASCADE CONSTRAINTS;
CREATE TABLE TRACES.TRAVEL
(
START_DATE DATE,
END_DATE DATE
);
DROP TABLE TRACES.BLACK_OUT_DATES CASCADE CONSTRAINTS;
CREATE TABLE TRACES.BLACK_OUT_DATES
(
BO CHAR( 1 BYTE ),
START_DATE DATE,
END_DATE DATE
);
/*
TEST CASE 1
-------------------------------------------------------------------
Expected Results:
01/01/0001 09/02/2011
16/02/2011 01/04/2011
21/04/2011 10/05/2011
16/06/2011 19/11/2011
30/11/2011 31/12/9999
Visually:
Travel:
----------------------------------------------------
BO:
--[--]----------------------------------------------
---------------[------]-----------------------------
-----------------------------[---------------]------
Result:
[-]---[--------]-------[-----]----------------[-----]
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '0001-01-01', DATE '9999-12-31' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-10', DATE '2011-02-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-04-02', DATE '2011-04-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-05-11', DATE '2011-06-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-11-20', DATE '2011-11-29' );
--INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-05-09', DATE '2011-05-12' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 2
-------------------------------------------------------------------
Expected Results:
01/01/2011 01/02/2011
07/05/2011 06/07/2011
21/07/2011 31/12/2011
Visually:
Travel:
[------------------------------------------------------]
BO:
--[----------------------]------------------------------
---------------[--]-------------------------------------
---------------------------------[--------]-------------
----------------------------------------[--------]------
Result:
[--]---------------------[---------]--------------[----]
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-01-01', DATE '2011-12-31' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-02', DATE '2011-05-06' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-03-03', DATE '2011-03-05' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-07-07', DATE '2011-07-09' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-07-08', DATE '2011-07-20' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 3
-------------------------------------------------------------------
Expected Results:
04/05/2011 03/06/2011
21/06/2011 07/08/2011
Visually:
Travel:
[------------------------------------------------------]
BO:
--[----------------------]------------------------------
---------------[--]-------------------------------------
---------------------------------[--------]-------------
----------------------------------------[--------]------
Result:
[--]---------------------[---------]--------------[----]
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-04-02', DATE '2011-10-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-01-01', DATE '2011-05-03' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-06-04', DATE '2011-06-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-06-06', DATE '2011-06-08' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-08-08', DATE '2011-12-30' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-08-08', DATE '2011-12-30' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 4
-------------------------------------------------------------------
Expected Results:
21/02/2011 09/04/2011
26/04/2011 09/05/2011
Visually:
Travel:
----[-------------------------]-------------------------
BO:
--[----]------------------------------------------------
----[----]----------------------------------------------
-------------[--------]---------------------------------
------------------[--]----------------------------------
--------------------------[--------]--------------------
Result:
----------[--]--------[--]-----------------------------
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-02-10', DATE '2011-05-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-02', DATE '2011-02-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-02-10', DATE '2011-02-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-04-10', DATE '2011-04-25' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-04-15', DATE '2011-04-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-05-10', DATE '2011-05-20' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 5
-------------------------------------------------------------------
Expected Results:
21/02/2011 04/05/2011
Visually:
Travel:
------[-------------------------]-----------------------
BO:
-[-----]------------------------------------------------
--[--]--------------------------------------------------
----------------------------[--------]------------------
------------------------------[-----]-------------------
-------------------------------[--]---------------------
Result:
--------[-------------------]---------------------------
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-02-10', DATE '2011-05-17' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-02-05', DATE '2011-02-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'B', DATE '2011-02-07', DATE '2011-02-09' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'C', DATE '2011-05-05', DATE '2011-05-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'D', DATE '2011-05-07', DATE '2011-05-15' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'E', DATE '2011-05-09', DATE '2011-05-12' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
/*
TEST CASE 6
-------------------------------------------------------------------
Expected Results:
No Result
Visually:
Travel:
------[----------------------------]--------------------
BO:
--[---------------------------------------]-------------
Result:
No Result
*/
TRUNCATE TABLE TRACES.TRAVEL;
TRUNCATE TABLE TRACES.BLACK_OUT_DATES;
INSERT INTO TRACES.TRAVEL( START_DATE, END_DATE ) VALUES ( DATE '2011-02-10', DATE '2011-09-20' );
INSERT INTO TRACES.BLACK_OUT_DATES( BO, START_DATE, END_DATE ) VALUES ( 'A', DATE '2011-01-05', DATE '2011-10-10' );
COMMIT;
SELECT * FROM BLACK_OUT_DATES;
SELECT * FROM TRAVEL;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这将返回旅行日期范围内但不在限制日期列表中的所有日期的离散列表,然后使用 Oracle - 将值从行转换为范围:
结果:
This returns a discrete list of all dates that exist in the Travel Dates range but not in the Blackout Dates list, and then combines them using Oracle - Convert value from rows into ranges:
Result:
您的表:
以及查询,该查询考虑了完全重叠的停电期:
如果您的 black_out_dates 表包含 N 行,则最多有 N+1 个间隙。该查询在 [2011-01-03,2011-01-03] 组成一个虚拟的中断日期期间,然后使用分析函数 LEAD 来确定下一个中断日期的开始位置。完全重叠的周期会被 ROW_NUMBER 分析函数删除,因为它们会弄乱间隙周期。
编辑 2011 年 3 月 14 日
对于这些表:
我之前的查询仍然无法正确处理重叠周期。所以这里是一个修订版本,方便地存储在视图 v:
和测试结果中:
问候,
抢。
Your tables:
And the query, which takes into account completely overlapping black out periods:
If your black_out_dates table contains N rows, then there at most N+1 gaps. The query makes up one dummy black out date period at [2011-01-03,2011-01-03], and then uses the analytic function LEAD to determine where the next black out date starts. Completely overlapping periods are removed by the ROW_NUMBER analytic functions, because they mess up the gap periods.
EDIT 14-3-2011
With these tables:
My previous query still did not handle overlapping periods correctly. So here is a revised version, conveniently stored in view v:
And the test results:
Regards,
Rob.