我需要根据每种状态的开始时间和结束时间(即特定状态何时开始以及该状态何时结束)创建从/到日期的输出。记录ID为2的记录。处理从01/04/2019开始,到添加下一个状态的01/05/2019结束。
这是示例脚本:
CREATE TABLE mytable (ID NUMBER, PARENT_ID NUMBER, STATUS VARCHAR2(20), ADDED_DATE DATE);
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(1, 123, 'Requested', TO_DATE('01/01/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(2, 123, 'Processing', TO_DATE('01/04/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(3, 123, 'Approved', TO_DATE('01/05/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(4, 567, 'Requested', TO_DATE('03/12/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(5, 567, 'Processing', TO_DATE('03/13/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(6, 4547, 'Requested', TO_DATE('04/22/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(7, 4547, 'Processing', TO_DATE('04/24/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(8, 4547, 'On-hold', TO_DATE('04/27/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(9, 4547, 'Denied', TO_DATE('05/05/2019', 'MM/DD/YYYY'));
INSERT INTO MYTABLE (ID, PARENT_ID, STATUS, ADDED_DATE) VALUES
(10, 15, 'Requested', TO_DATE('03/16/2019', 'MM/DD/YYYY'));
所需的输出:
ID PARENT_ID STATUS FROM_DT TO_DT
1 123 Requested 01/01/2019 01/04/2019
2 123 Processing 01/04/2019 01/05/2019
3 123 Approved 01/05/2019 SYSDATE
4 567 Requested 03/12/2019 03/13/2019
5 567 Processing 03/13/2019 SYSDATE
6 4547 Requested 04/22/2019 04/24/2019
7 4547 Processing 04/24/2019 04/27/2019
8 4547 On-hold 04/27/2019 05/05/2019
9 4547 Denied 05/05/2019 SYSDATE
10 15 Requested 03/16/2019 SYSDATE
答案 0 :(得分:0)
最简单的方法是使用内置的“窗口功能” Lead
,它使您可以期待许多记录,在这种情况下,只有一条记录。这是应该做的查询。
SELECT
mt.ID,
mt.PARENT_ID,
mt.STATUS,
mt.ADDED_DATE as FROM_DT,
LEAD(mt.ADDED_DATE, 1, SYSDATE ) OVER (PARTITION BY mt.PARENT_ID ORDER BY mt.ID) as TO_DT
FROM
mytable mt
ORDER BY
mt.ID
可以通过其他方式获得相同的结果,但这是最有效的。要说明LEAD
的语法:
LEAD(mt.ADDED_DATE, 1, SYSDATE)
我们得到ADDED_DATE
的值,1
在当前组(或Window)中当前行的前面,如果没有这样的行,我们将返回{{1 }}
SYSDATE
此部分定义组(窗口)。 LEAD功能仅在组内起作用。在我们的例子中,定义组的是OVER(PARTITION BY mt.PARENT_ID ORDER BY mt.ID)
。不同的PARENT_ID
,不同的组,因此您在PARENT_ID
的一行上运行的LEAD无法找到PARENT_ID = 123
的值。您还可以按多个字段进行分区,只需将其用逗号分隔即可。窗口将是行集,其中所有这些字段在整个行中都一致。当我们从“下一行”中查找日期时,重要的是在窗口中正确排列行,否则向前看1行可能无法满足您的期望。这就是PARENT_ID <> 123
进入的地方。