Думаю, я понимаю. Вам просто нужно либо сопоставить группы, либо создать новые. Я не собираюсь быть привязанным к вашим соглашениям об именах - это немного сложно. Фактически, я бы просто сделал группы числами, а не строками.
Но это генерирует новые группы:
with newvalues as (
select 'v5' as val, 'a' as matcher union all
select 'v6' as val, 'a' as matcher union all
select 'v7' as val, 'b' as matcher union all
select 'v8' as val, 'c' as matcher union all
select 'v9' as val, 'c' as matcher
)
select nv.*,
coalesce(i.groupid,
'new_group' || dense_rank() over (partition by i.groupid order by nv.matcher)::text
) as groupid
from newvalues nv left join
initial i
on nv.matcher = i.matcher;
И это вставляет значения:
with newvalues as (
select 'v5' as val, 'a' as matcher union all
select 'v6' as val, 'a' as matcher union all
select 'v7' as val, 'b' as matcher union all
select 'v8' as val, 'c' as matcher union all
select 'v9' as val, 'c' as matcher
)
insert into initial (groupid, val, matcher)
select coalesce(i.groupid,
'new_group' || dense_rank() over (partition by i.groupid order by nv.matcher)::text
) as groupid,
nv.val, nv.matcher
from newvalues nv left join
initial i
on nv.matcher = i.matcher;
Здесь - скрипт db <>.