Das wäre auch ne Möglichkeit:

with
test_data(kdnr, ans1, name1, ort1, ans2, name2, ort2, ans3, name3, ort3) as (
values
(110, 10, 'Markus', 'München', 20, 'Jürgen', 'Köln', 30, 'Peter', 'Berlin'),
(120, 20, 'Stefan', 'Augsburg', 0, '', '', 0, '', '')
),

test_data_tab(kdnr, ans, name, ort) as (
select
tab_data.*
from
test_data

cross join lateral(
values
(kdnr, ans1, name1, ort1),
(kdnr, ans2, name2, ort2),
(kdnr, ans3, name3, ort3)
) as tab_data(kdnr, ans, name, ort)
where
ans <> 0
)

select * from test_data_tab