【问题标题】:How to find the difference between dates, which are based on conditions from previous rows如何根据前几行的条件查找日期之间的差异
【发布时间】:2019-12-31 01:59:15
【问题描述】:

这是我的桌子:

CREATE TABLE ABC
 (
     nekey NUMBER(5), 
     seq number(20),
     task varchar2(10), 
     status varchar2(10),
     entrydat date, 
     findat DATE
  );

价值观:

insert into ABC (nekey, seq, task, status, entrydat, findat) values (1, 3, 'Build', 'Closed', 
to_date('08-01-2019', 'mm-dd-yyyy'), to_date('08-04-2019', 'mm-dd-yyyy'));

insert into ABC (nekey, seq, task,status, entrydat, findat) values (1, 6,'Paint','Open', null, 
null); 

insert into ABC (nekey,seq,  task,status, entrydat, findat) values (1, 9,'Assemble','Pending', null, 
null);

insert into ABC (nekey,seq, task,status, entrydat, findat) values (2, 3,'Build', 'Closed',
to_date('08-02-2019', 'mm-dd-yyyy'), to_date('08-05-2019', 'mm-dd-yyyy'));

insert into ABC (nekey,seq, task, status,entrydat, findat) values (2, 6,'Paint', 'Closed',
to_date('08-05-2019', 'mm-dd-yyyy'), to_date('08-09-2019', 'mm-dd-yyyy')); 

insert into ABC (nekey,seq, task, status,entrydat, findat) values (2,9, 'Assemble', 'Open', null, 
null);

现在我想得到如下输出:

对于每个键,任务按以下顺序排列。

1) 构建

2) 绘画

3) 组装。 ((但我的数据有20多个任务)我以这3个为例)

所以,我必须计算“天”列,如附图所示。

所以当

1) 状态为关闭然后 findate-entrydate

2)当状态为 Open 或 Null 时(sysdate - previous task 的 Findate )(我已经解决了第一个任务是 Open 的情况,它是 projectstartdate - entrydate)

3) 当状态为 Pending 时不计算

我如何在 Oracle SQL 中做到这一点,

【问题讨论】:

  • 我们可以解决您发布的问题,但这可能不足以解决您的实际问题。具体来说:您说您有 15 个不同的“任务”,而且它们似乎是完全有序的。是什么给出了这个命令?您是否有一个“任务”表,其中显示每个任务,并按顺序排列?如果是这样,发布一个小样本也会有所帮助(在这种情况下,一个小表,三行用于三个任务,两列用于“任务名称”和“seq_num”(序列号)。
  • 另外,如果 FIRST 任务处于 OPEN 状态怎么办?那么就没有上一个任务的FINDATE了;是否应该将 FINDATE 视为 NULL(在这种情况下,与 SYSDATE 的差异也是 NULL)?
  • 是的,我可以修改问题,
  • 我已经解决了第一个任务为Null的情况,我只是减去ProjectStartDate - Entrydate
  • 请运行您的 CREATE TABLE 和 INSERT 语句(在您可以从头开始重新创建表的测试模式中),并调试它们直到它们工作。您的陈述中有许多错误。

标签: sql oracle date plsql


【解决方案1】:

请注意,CREATE TABLE 和 INSERT 语句中有许多错误。特别是,INSERT 语句创建了 NEKEY = 1 的五行,但您的输出显示了 NEKEY = 1 的三行(以及 NEKEY = 2 的三行)。下面显示的输出基于修复语句中的所有错误,并更改两个 INSERT 语句中的 NKEY 以匹配您的输出。

您的问题的答案是select 子句中的case 表达式,在需要时使用解析lag() 函数。对于 NEKEY 的第一行的状态 OPEN,此查询将返回 NULL。在您原始帖子下对我的答复中,您说您可以自己处理(但是您提到了帖子中任何地方都没有出现的表达方式,因此我将其省略了-供您修复,可能使用NVL(...) 调用)。

select abc.*, 
       case status when 'Closed'  then findat - entrydat
                   when 'Pending' then null
                   else trunc(sysdate) - lag(findat) 
                                           over (partition by nekey order by seq) 
       end as days
from   abc
;

     NEKEY        SEQ TASK       STATUS     ENTRYDAT   FINDAT           DAYS
---------- ---------- ---------- ---------- ---------- ---------- ----------
         1          3 Build      Closed     08/01/2019 08/04/2019          3
         1          6 Paint      Open                                     22
         1          9 Assemble   Pending                                    
         2          3 Build      Closed     08/02/2019 08/05/2019          3
         2          6 Paint      Closed     08/05/2019 08/09/2019          4
         2          9 Assemble   Open                                     17

【讨论】:

  • dbfiddle.uk/…我这里试试
  • 嗨@mathguy,我也想知道我是否可以减去 findates。例如:当序列不在 3 并且状态为关闭时(2019 年 8 月 9 日 - 2019 年 8 月 5 日),即 4
  • @StackOne - 我不明白你的最后一个问题。我的解决方案不是已经这样做了吗?
  • 我想出了我对上一个问题的答案:dbfiddle.uk/… 已附加
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2018-04-08
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多