Fonctionne dans Oracle 12+.
Dans 11g, vous pouvez concaténer des éléments de collection en utilisant listagg ou UDF.
with
function collagg(p in sys.ku$_vcnt) return varchar2 is
result varchar2(4000);
begin
for i in 1..p.count loop result := result || '; ' || p(i); end loop;
return(substr(result,2));
end;
t(id, name, attr, val) as
( select 1, 'Ford', 'A', 'B' from dual union all
select 1, 'Ford', 'B', 'C' from dual union all
select 1, 'Ford', 'C', 'D' from dual union all
select 2, 'BMW', 'A', 'B' from dual union all
select 2, 'BMW', 'C', 'D' from dual union all
select 2, 'BMW', 'F', 'G' from dual union all
select 3, 'TESLA', 'Z', 'Y' from dual union all
select 3, 'TESLA', 'E', 'F' from dual union all
select 3, 'TESLA', 'A', 'B' from dual)
, t0 as
(select id, name,
cast(collect(cast(attr||':'||val as varchar2(4000))) as sys.ku$_vcnt) c
from t t1
group by id, name)
select t1.id baseid,
t1.name basename,
t2.id tgtid,
t2.name tgtname,
collagg(t1.c multiset intersect t2.c) matchedon,
collagg(t1.c multiset except t2.c) baseonly,
collagg(t2.c multiset except t1.c) tgtonly
from t0 t1 join t0 t2 on t1.id < t2.id;