I've tried a few things but cant get there, is there a nice way of doing it?
Not sure what exactly was /could be an issue here as it is as simple/straightforward as below
select id, Name,
[struct<key string, value string>('DOB', DOB),('Sex', Sex)] info
from `project.dataset.table`
with output

Meantime, usually the issue comes when you don't know those columns names in advance and want to have generic approach - in this case you can use below approach where column names DOB and Sex are not being used
select id, Name,
array(
select as struct
split(replace(kv, '"', ''),':')[offset(0)] key,
split(replace(kv, '"', ''),':')[offset(1)] value,
from unnest(split(trim(to_json_string((select as struct * except (id, name) from unnest([t]))), '{}'))) kv
) info
from `project.dataset.table` t
with exact same result/output
