create table table1(
a varchar2(20) not null,
b varchar2(20) not null,
c varchar2(20) not null
)
/
create table ctrs (
val varchar2(20) unique,
ctr_a int,
ctr_b int,
ctr_c int,
check(ctr_a*ctr_b+ctr_a*ctr_c+ctr_b*ctr_c=0)
)
/
create trigger table1_trg
before insert or update or delete on table1
for each row
begin
if deleting then
update ctrs set ctr_a = ctr_a - 1 where val = :old.a;
update ctrs set ctr_b = ctr_b - 1 where val = :old.b;
update ctrs set ctr_c = ctr_c - 1 where val = :old.c;
elsif inserting then
merge into ctrs using (
select :new.a as x from dual union all
select :new.b as x from dual union all
select :new.c as x from dual
)
on (val = x)
when not matched then
insert (val, ctr_a, ctr_b, ctr_c) values (x, 0, 0, 0);
update ctrs set ctr_a = ctr_a + 1 where val = :new.a;
update ctrs set ctr_b = ctr_b + 1 where val = :new.b;
update ctrs set ctr_c = ctr_c + 1 where val = :new.c;
else
update ctrs set ctr_a = ctr_a - 1 where val = :old.a;
update ctrs set ctr_b = ctr_b - 1 where val = :old.b;
update ctrs set ctr_c = ctr_c - 1 where val = :old.c;
merge into ctrs using (
select :new.a as x from dual union all
select :new.b as x from dual union all
select :new.c as x from dual
)
on (val = x)
when not matched then
insert (val, ctr_a, ctr_b, ctr_c) values (x, 0, 0, 0);
update ctrs set ctr_a = ctr_a + 1 where val = :new.a;
update ctrs set ctr_b = ctr_b + 1 where val = :new.b;
update ctrs set ctr_c = ctr_c + 1 where val = :new.c;
end if;
end;
/
fiddle