Você está 90% do caminho até lá:
with cte as (
select
id,
case [key]
when 'A'
then str_val
end as A,
case [key]
when 'B'
then str_val
end as B,
case [key]
when 'C'
then date_val
end as C,
case [key]
when 'D'
then num_val
end as D,
case [key]
when 'E'
then str_val
end as E
from test_table
)
select id, max(A) as A, max(B) as B, max(C) as C, max(D) as D, max(E) as E
from cte
group by id