Как добавить флаг к строкам после определенного значения в ключе в Oracle SQL? - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть следующие данные:

Key Stage CreateDate
AAF 0     01-Jan-2018
AAF 0     02-Jan-2018
AAF 0     10-Jan-2018
AAF 20    20-Jan-2018
AAF 40    20-Mar-2018
AAF 0     01-May-2018
AAF 0     10-May-2018
AAF 0     20-May-2018
AAF 30    20-Jun-2018
AAF 0     20-Jul-2018   
AAF 100   20-Jul-2018       

Я в основном пытаюсь рассчитать дни, проведенные на каждом этапе. В настоящее время я беру минимальную дату на каждом этапе и нахожу разницу между минимальнымдата следующей стадии:

select 
key,
stage,
cast(extract (day from max(next_dt) - min(createddate)) as number) as interval_days
from
(
select 
key,
stage,
createddate
lead(createddate,1) over (partition by  key order by createddate) next_dt
from  oppstages
)
group by key,stage 

Как видно, иногда стадия прогрессирует от 0-40, но снова возвращается к 0. Таким образом, приведенная выше логика не работает правильно, и явидя необходимость сгруппировать 0-40 как одну категорию, и что-либо после 40 как следующую категорию и т. д. (если этап уменьшается и перезапускается с новым меньшим номером этапа).Приведенный ниже запрос дает мне точку, где вероятность снижается, но я не могу пометить, чтобы сгруппировать строки дальше.

select key,
stage,
createddate, 
next_dt,
next_prob,
case when   next_prob < stage  then 1   else 0 end as valid_flag,
from 
(
select 
key,
stage,
createddate,
lead(createddate,1) over (partition by  key order by createddate) next_dt, 
coalesce(lead(stage,1) over (partition by  key order by createddate),101) next_prob, 
from oppstages
) a

Я ожидаю, что этот вывод, чтобы я мог сгруппировать, используя флаг для расчета дней, потраченных накаждый экземпляр:

Key Stage CreateDate    Flag
AAF 0     01-Jan-2018   1
AAF 0     02-Jan-2018   1
AAF 0     10-Jan-2018   1
AAF 20    20-Jan-2018   1
AAF 40    20-Mar-2018   1
AAF 0     01-May-2018   2
AAF 0     10-May-2018   2
AAF 0     20-May-2018   2
AAF 30    20-Jun-2018   2
AAF 10     20-Jul-2018   3
AAF 100   20-Jul-2018   3

спасибо.

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

У вас проблема с пробелами и островами.Простое решение использует разницу номеров строк.Это определяет группу.

select t.*, (seqnum_2 - seqnum_1) as grp
from (select os.*,
             row_number() over (partition by key order by createdate) as seqnum,
             row_number() over (partition by key, stage order by createdate) as seqnum_2
      from oppstages os
     ) os;

То, что вы, вероятно, хотите, является агрегацией:

select key, stage, min(createdate), max(createdate),
       lead(min(createdate)) over (partition by key, stage, seqnum - seqnum_2 order by createdate) as next_creatdate
from (select os.*,
             row_number() over (partition by key order by createdate) as seqnum,
             row_number() over (partition by key, stage order by createdate) as seqnum_2
      from oppstages os
     ) os
group by key, stage, (seqnum_2 - seqnum)

Я не уверен, какую логику вы хотите для продолжительности, но это должно иметь всенеобходимая информация.

0 голосов
/ 18 сентября 2018

Вы можете попытаться использовать lag оконную функцию, чтобы получить Stage предыдущее значение.

Затем используйте CASE WHEN check PREVAL > STAGE do увеличивается 1.

CREATE TABLE T(
  Key varchar(50),
  Stage int,
  CreateDate date
);



INSERT INTO T VALUES ('AAF',0,TO_DATE('01-01-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',0,TO_DATE('02-01-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',0,TO_DATE('10-01-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',20,TO_DATE('20-01-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',40,TO_DATE('20-03-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',0,TO_DATE('01-05-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',0,TO_DATE('10-05-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',0,TO_DATE('20-05-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',30,TO_DATE('20-06-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',10,TO_DATE('20-07-2018','dd-mm-yyyy'));  
INSERT INTO T VALUES ('AAF',100,TO_DATE('20-07-2018','dd-mm-yyyy'));  

Запрос 1 :

SELECT t1.KEY,
       t1.STAGE,
      (SUM(CASE WHEN PREVAL > STAGE THEN 1 ELSE 0 END) over (partition by Key order by CreateDate) + 1)  Flag
FROM (
  SELECT T.*,lag(Stage) over (partition by Key  order by CreateDate) preVAL
  FROM T 
)t1

Результаты :

| KEY | STAGE | FLAG |
|-----|-------|------|
| AAF |     0 |    1 |
| AAF |     0 |    1 |
| AAF |     0 |    1 |
| AAF |    20 |    1 |
| AAF |    40 |    1 |
| AAF |     0 |    2 |
| AAF |     0 |    2 |
| AAF |     0 |    2 |
| AAF |    30 |    2 |
| AAF |    10 |    3 |
| AAF |   100 |    3 |
...