Это то, что я придумал. Открыт для лучших решений. Спасибо
with HAVE_tmp as
(
select t.*,rownum as seq from HAVE t
)
,TBL1 as
(
SELECT
seq
, DOB
, SID
,first_value(FNAME ignore NULLS) over (partition by SID,DOB order by DOB) as fname
,first_value(LNAME ignore NULLS) over (partition by SID,DOB order by DOB) as lname
,first_value(GNDR ignore NULLS) over (partition by SID,DOB order by DOB) as GNDR
FROM HAVE_tmp
where trim(SID) is not null and trim(DOB) is not null
)
,TBL2 as
(
select t2.*,
first_value(SID ignore NULLS) over (partition by fname,lname order by SEQ) as ID_1
from (
select * from TBL1
union all
select
seq
, DOB
, SID
,FNAME
, LNAME
,GNDR
FROM HAVE_tmp
where trim(SID) is null or trim(DOB) is null
)t2
)
,TBL_FINAL as
(
select t.FNAME,t.LNAME,t.DOB, t.SID,t.GNDR,t1.ID_1 as new_id
from HAVE_tmp t
inner join TBL2 t1 on
t.seq=t1.seq
)
select * from TBL_FINAL