Вам потребуется использовать вложенные подзапросы или использовать функциональность SAS Retain
на шаге данных, чтобы выполнить это.
Решение ниже использует подзапросы, см. Мои встроенные комментарии:
data have;
/* infile datalines dlm=',' dsd; */
length Obs 8. MEMNUM $22. ADM $9. LINE $1. FROM 8. TO 8. FROM_NEW 8. TO_NEW 8. TOS $6. order 8. ;
format FROM date9. TO date9. FROM_NEW date9. TO_NEW date9. ;
informat FROM date9. TO date9. FROM_NEW date9. TO_NEW date9. ;
input
Obs MEMNUM $ ADM $ LINE $ FROM TO FROM_NEW TO_NEW TOS $ order ;
datalines;
1 9840964190000001 237696870 X 23OCT2016 23NOV2016 23OCT2016 30OCT2016 FAC_IP 1
2 9840964190000001 237696870 R 23OCT2016 23NOV2016 . 23NOV2016 FAC_IP 2
3 9840964190000001 237696870 X 23OCT2016 23NOV2016 02NOV2016 03NOV2016 FAC_IP 3
4 9840964190000001 237696870 X 23OCT2016 23NOV2016 05NOV2016 09NOV2016 FAC_IP 4
5 9840964190000001 237696870 X 23OCT2016 23NOV2016 11NOV2016 14NOV2016 FAC_IP 5
6 9840964190000001 237696870 . 23OCT2016 23NOV2016 25OCT2016 25OCT2016 PRO_IP .
7 9840964190000001 237696870 . 23OCT2016 23NOV2016 26OCT2016 26OCT2016 PRO_IP .
8 9840964190000001 237696870 . 23OCT2016 23NOV2016 27OCT2016 27OCT2016 PRO_IP .
9 9840964190000001 237696870 . 23OCT2016 23NOV2016 28OCT2016 28OCT2016 PRO_IP .
10 9840964190000001 237696870 . 23OCT2016 23NOV2016 29OCT2016 29OCT2016 PRO_IP .
11 9840964190000001 237696870 . 23OCT2016 23NOV2016 30OCT2016 30OCT2016 PRO_IP .
12 9840964190000001 237696870 . 23OCT2016 23NOV2016 02NOV2016 02NOV2016 PRO_IP .
13 9840964190000001 237696870 . 23OCT2016 23NOV2016 03NOV2016 03NOV2016 PRO_IP .
14 9840964190000001 237696870 . 23OCT2016 23NOV2016 06NOV2016 06NOV2016 PRO_IP .
15 9840964190000001 237696870 . 23OCT2016 23NOV2016 07NOV2016 07NOV2016 PRO_IP .
16 9840964190000001 237696870 . 23OCT2016 23NOV2016 08NOV2016 08NOV2016 PRO_IP .
17 9840964190000001 237696870 . 23OCT2016 23NOV2016 11NOV2016 11NOV2016 PRO_IP .
18 9840964190000001 237696870 . 23OCT2016 23NOV2016 12NOV2016 12NOV2016 PRO_IP .
19 9840964190000001 237696870 . 23OCT2016 23NOV2016 13NOV2016 13NOV2016 PRO_IP .
20 9840964190000001 237696870 . 23OCT2016 23NOV2016 14NOV2016 14NOV2016 PRO_IP .
21 9840964190000001 237696870 . 23OCT2016 23NOV2016 20NOV2016 20NOV2016 PRO_IP .
22 9840964190000001 237696870 . 23OCT2016 23NOV2016 21NOV2016 21NOV2016 PRO_IP .
23 9840964190000001 237696870 . 23OCT2016 23NOV2016 22NOV2016 22NOV2016 PRO_IP .
24 9840964190000001 237696870 . 23OCT2016 23NOV2016 23NOV2016 23NOV2016 PRO_IP .
25 9840964190000001 244243815 R 04DEC2016 17DEC2016 04DEC2016 . FAC_IP 1
26 9840964190000001 244243815 X 04DEC2016 17DEC2016 14DEC2016 17DEC2016 FAC_IP 2
27 9840964190000001 244243815 . 04DEC2016 17DEC2016 04DEC2016 04DEC2016 PRO_IP .
28 9840964190000001 244243815 . 04DEC2016 17DEC2016 05DEC2016 05DEC2016 PRO_IP .
29 9840964190000001 244243815 . 04DEC2016 17DEC2016 06DEC2016 06DEC2016 PRO_IP .
30 9840964190000001 244243815 . 04DEC2016 17DEC2016 07DEC2016 07DEC2016 PRO_IP .
31 9840964190000001 244243815 . 04DEC2016 17DEC2016 08DEC2016 08DEC2016 PRO_IP .
32 9840964190000001 244243815 . 04DEC2016 17DEC2016 14DEC2016 14DEC2016 PRO_IP .
33 9840964190000001 244243815 . 04DEC2016 17DEC2016 15DEC2016 15DEC2016 PRO_IP .
34 9840964190000001 244243815 . 04DEC2016 17DEC2016 16DEC2016 16DEC2016 PRO_IP .
35 9840964190000001 244243815 . 04DEC2016 17DEC2016 17DEC2016 17DEC2016 PRO_IP .
;
run;
proc sql;
create table missing_dates as
select MEMNUM , ADM , FROM_NEW , TO_NEW , MAX_FROM_NEW , Max_TO_NEW ,
max(FNL) as FNL format=date9., min(TNL) as TNL format=date9.
from (
select t1.*, t2.Max_Order, t3.FROM_NEW as MAX_FROM_NEW , t3.TO_NEW as Max_TO_NEW ,
t4.FROM_NEW as FNL, t4.TO_NEW as TNL
from
/* Identify Missing dates*/
(select * from have where FROM_NEW = . or TO_NEW=.) as t1
left join
/* Identify Max order */
(select MEMNUM, ADM, max(order) as Max_Order
from have where TOS='FAC_IP' group by MEMNUM, ADM ) as t2 on t1.MEMNUM=t2.MEMNUM and t1.ADM = t2.ADM
/* Join Max Order with the rest of the Data */
inner join have as t3 on t3.TOS='FAC_IP' and t3.MEMNUM=t2.MEMNUM and t3.ADM = t2.ADM and t3.order=t2.Max_Order
/* Join Max Order with PRO_IP */
left join
(select MEMNUM, ADM, FROM_NEW , TO_NEW from have where TOS='PRO_IP' group by MEMNUM, ADM ) as t4 on t1.MEMNUM=t4.MEMNUM and t1.ADM = t4.ADM
) as want
where case when (FROM_NEW=. and TNL> Max_TO_NEW) then 1
when (TO_NEW=. and FNL < MAX_FROM_NEW) then 1
else 0
end
group by MEMNUM , ADM , FROM_NEW , TO_NEW , MAX_FROM_NEW , Max_TO_NEW
;
quit;
proc sql;
create table update_mising as select
A.Obs, A.MEMNUM, A.ADM , A.LINE ,A.FROM , A.TO ,
coalesce(A.FROM_NEW,B.TNL) as FROM_NEW format=date9. ,
coalesce(A.TO_NEW,B.TNL) as TO_NEW format=date9. ,
A.TOS , A.order
from have A left join missing_dates B
on (A.FROM_NEW = . or A.TO_NEW=.) and A.MEMNUM=B.MEMNUM and A.ADM = B.ADM
order by A.OBS
;
quit;
Финальный стол:
![Output](https://i.stack.imgur.com/n4SQS.jpg)