Are you looking for something like
select ID,
change_id,
update_time,
substr(max(case when columnname = 'change_col_1' then cast(update_time as char(30)) ||change_log_to else null end) over (partition by ID,change_id order by update_time, columnname rows between unbounded preceding and current row ),31) as last_val_col1,
substr(max(case when columnname = 'change_col_2' then cast(update_time as char(30)) ||change_log_to else null end) over (partition by ID,change_id order by update_time, columnname rows between unbounded preceding and current row ),31) as last_val_col2,
substr(max(case when columnname = 'change_col_3' then cast(update_time as char(30)) ||change_log_to else null end) over (partition by ID,change_id order by update_time, columnname rows between unbounded preceding and current row ),31) as last_val_col3,
substr(max(case when columnname = 'change_col_4' then cast(update_time as char(30)) ||change_log_to else null end) over (partition by ID,change_id order by update_time, columnname rows between unbounded preceding and current row ),31) as last_val_col4,
substr(max(case when columnname = 'change_col_5' then cast(update_time as char(30)) ||change_log_to else null end) over (partition by ID,change_id order by update_time, columnname rows between unbounded preceding and current row ),31) as last_val_col5
from stage_tbl
qualify row_number() over (partition by id, change_id, update_time order by columnname desc ) = 1
Its not 100% as of your expected results but it is also unclear to me how
INSERT INTO expected_res VALUES (1234,5678,'2013-07-01 07:00.00.000000','erf','lks',NULL,'rfd','lop');
should be generated from your stg data...
Are you looking for something like
Its not 100% as of your expected results but it is also unclear to me how
INSERT INTO expected_res VALUES (1234,5678,'2013-07-01 07:00.00.000000','erf','lks',NULL,'rfd','lop');
should be generated from your stg data...