繁体   English   中英

从多行/单列获取开始/结束日期

[英]Getting Start/End date from multiple rows/single column

我需要根据每个状态的开始时间和结束时间创建from / to日期的输出,换句话说,当特定状态开始时和此状态结束时,例如,对于具有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  

最简单的方法是使用内置的“Window fuction” 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_DATE1领先于当前组(或窗口)内的当前行的行,如果没有这样的行我们返回SYSDATE

OVER(PARTITION BY mt.PARENT_ID ORDER BY mt.ID)

这部分定义了组(Window)。 LEAD功能仅适用于组内。 在我们的例子中,定义组的是PARENT_ID 不同的PARENT_ID ,不同的组,因此您在PARENT_ID = 123的行上运行LEAD无法找到PARENT_ID <> 123 您还可以按多个字段进行分区,只需用逗号分隔即可。 窗口将是所有这些字段在整个集合中一致的行集。 当我们从“下一行”查找日期时,重要的是行在窗口内正确排序,否则向前看一行可能无法满足您的期望。 这就是ORDER BY用武之地。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM