Чтобы обойти пределы Oracle, вы можете идентифицировать все пары dept
с одинаковыми атрибутами. Затем используйте имя минимального отдела (или рейтинг по нему) в качестве группы.
Предполагая, что пары уникальны, следующее генерирует совпадающие пары:
with dn as (
select dept, attr, count(*) over (partition by dept) as cnt
from t
)
select dn1.dept, dn2.dept
from dn dn1 join
dn dn2
on dn2.att1 = dn1.att1 and
dn2.cnt = dn1.cnt
group by dn1.dept, dn2.dept, dn1.cnt
having count(*) = dn1.cnt -- all match
Обратите внимание, что это сохраняет ВСЕ пары с одинаковыми значениями att1
, поэтому все dept
соответствуют друг другу в этом результате.
Для окончательного назначения группы:
with dn as (
select dept, attr, count(*) over (partition by dept) as cnt
from t
)
select dept1, min(dept2) as first_dept,
dense_rank() over (order by min(dept2)) as grp_number
from (select dn1.dept as dept1, dn2.dept as dept2
from dn dn1 join
dn dn2
on dn2.att1 = dn1.att1 and
dn2.cnt = dn1.cnt
group by dn1.dept, dn2.dept, dn1.cnt
having count(*) = dn1.cnt
) dd
group by dept1;
В общем, я предпочитаю listagg()
подход. Но если это невозможно, это также должно сработать.