Сначала необходимо нормализовать модель данных, чтобы можно было правильно присоединиться к списку кодов:
select a.id, a.name, x.*
from table_a a
left join lateral (
select b.code, b.name
from unnest(string_to_array(a.b_codes, ',')) as c(code)
join table_b b on b.code = c.code
) as x on true
;
Это возвращает следующий результат:
id | name | code | name
---+------+------+-----
1 | abc | a | xx
1 | abc | b | yy
2 | def | |
Коды могут быть агрегированы непосредственно в производной таблице (подзапрос):
select a.id, a.name, coalesce(x.codes, '[]') as codes
from table_a a
left join lateral (
select jsonb_agg(jsonb_build_object('code', b.code, 'name', b.name)) as codes
from unnest(string_to_array(a.b_codes, ',')) as c(code)
join table_b b on b.code = c.code
) as x on true
;
coalesce()
необходим для получения пустого массива для id = 2, в противном случае столбец codes
из производной таблицы будет null.
Теперь его можно преобразовать в JSON значения:
select jsonb_build_object('id', a.id, 'name', a.name, 'b_codes', coalesce(x.codes, '[]'))
from table_a a
left join lateral (
select jsonb_agg(jsonb_build_object('code', b.code, 'name', b.name)) as codes
from unnest(string_to_array(a.b_codes, ',')) as c(code)
join table_b b on b.code = c.code
) as x on true
;
Онлайн-пример