0

这个问题是这个问题的延续:(Oracle APEX - SQL - 创建顺序历史并计算每个阶段之间的天数

一些背景:

因此,对于我的一个应用程序,我决定需要能够捕获比以前更详细的指标。我的团队创建文档,特别是我想知道该文档在其开发的每个阶段花费了多长时间(以天为单位)。用于捕获此数据的表的结构如下:

 TBL_DOC_TIMELINE
 DOC_ENTRY_ID     DOC_ID     DOC_STATUS     DOC_CATEGORY     DOC_DATE       
 1                123        Planned        OPEN             06-05-2012    
 7                123        Draft          OPEN             06-15-2012
 38               123        Approval       OPEN             06-20-2012
 102              123        Published      CLOSED           06-30-2012

我们所有的文档都使用同一个表来实现这个功能,所以我不能简单地键入 DOC_ENTRY_ID,尽管它可能会有所帮助。我需要找到 DOC_ID 的最大 DOC_ENTRY_ID 然后计算。我这样做直到我到达“CLOSED”的 DOC_CATEGORY 并且在单元格中插入了哪个点“0”,因为那是该 DOC_ID 生命周期的结束。像这样:

 DOC_ENTRY_ID  DOC_ID  DOC_STATUS  DOC_CATEGORY  DOC_DATE     DOC_DURATION     
 1             123     Planned     OPEN          06-05-2012   10     
 7             123     Draft       OPEN          06-15-2012   5
 38            123     Approval    OPEN          06-20-2012   10
 102           123     Published   CLOSED        06-30-2012   0

这一切目前都归功于出色的 Tony Andrews,他为最终变成的 View 代码提供了粗略的草稿:

create or replace  view DOC_TIMELINE as
  select t.DOC_ENTRY_ID, t.DOC_ID, t.DOC_STATUS, t.DOC_CATEGORY, t.DOC_DATE
       , case when DOC_CATEGORY = 'CLOSED' then 0
            else lead(DOC_DATE) over (partition by DOC_ID order by DOC_ENTRY_ID)
                   - DOC_DATE
              end as duration
  from TBL_DOC_TIMELINE t;

我现在需要做的:

这一切都完美无缺,除了在我最初的通过时,我忘记了我的要求中一个非常重要的部分。我的目标是知道文档在每个阶段花费了多长时间,但我完全没有意识到我需要实时收集这些信息,而不仅仅是在文档关闭之后。使用当前设置,视图在其生命周期中间将如下所示:

 DOC_ENTRY_ID  DOC_ID  DOC_STATUS  DOC_CATEGORY  DOC_DATE     DOC_DURATION     
 1             123     Planned     OPEN          06-05-2012   10     
 7             123     Draft       OPEN          06-15-2012   5
 38            123     Approval    OPEN          06-20-2012   -

看到问题了吗?如果我需要知道该文档在 Approval 状态下花费了多长时间,那么我需要等到它离开该状态才能计算持续时间。因此,即使它可能已经处于该状态 20 天,我的指标也不会反映这一点。

如果给定 DOC_ID 的 MAX(DOC_ENTRY_ID) 具有 DOC_CATEGORY = 'OPEN',我需要做的是找到一些方法来调整上面的 View 代码以根据 SYSDATE() 计算该值。

 assuming SYSDATE() = '06-29-2012'
 DOC_ENTRY_ID  DOC_ID  DOC_STATUS  DOC_CATEGORY  DOC_DATE     DOC_DURATION     
 1             123     Planned     OPEN          06-05-2012   10     
 7             123     Draft       OPEN          06-15-2012   5
 38            123     Approval    OPEN          06-20-2012   9

这有什么意义吗?我想我需要在视图代码中添加另一个 CASE,但是 sytanx 给我带来了一些麻烦。对你们来说,这可能是一个简单的解决方案,但我对这类案例的熟悉程度和允许的 sytanx 是有限的,我的研究还没有发现任何相关的东西。

我真诚地感谢任何和所有的帮助。多谢你们!

4

1 回答 1

1

像这样的东西?-

create or replace  view DOC_TIMELINE as
  select t.DOC_ENTRY_ID, t.DOC_ID, t.DOC_STATUS, t.DOC_CATEGORY, t.DOC_DATE
       , case when DOC_CATEGORY = 'CLOSED' then 0
              when lead(DOC_DATE) over (partition by DOC_ID order by DOC_ENTRY_ID)
                   - DOC_DATE is null then trunc(sysdate)-trunc(DOC_DATE)
              else lead(DOC_DATE) over (partition by DOC_ID order by DOC_ENTRY_ID)
                   - DOC_DATE
              end as duration
  from TBL_DOC_TIMELINE t;

或因为lead(DOC_DATE)将始终null为 max DOC_ENTRY_ID(for a DOC_ID)-

create or replace  view DOC_TIMELINE as
  select t.DOC_ENTRY_ID, t.DOC_ID, t.DOC_STATUS, t.DOC_CATEGORY, t.DOC_DATE
       , case when DOC_CATEGORY = 'CLOSED' then 0
              when lead(DOC_DATE) over (partition by DOC_ID order by DOC_ENTRY_ID) 
                      is null then trunc(sysdate)-trunc(DOC_DATE)
              else lead(DOC_DATE) over (partition by DOC_ID order by DOC_ENTRY_ID)
                   - DOC_DATE
              end as duration
  from TBL_DOC_TIMELINE t;
于 2012-08-15T20:09:29.970 回答