Ваш текущий дизайн не нормализован и означает, что для достижения того, что вы хотите, требуется много усилий.
Для КАЖДОЙ таблицы терминов создайте до и после триггера вставки, до и после триггеров обновления и триггера после удаления при этом вы анализируете все таблицы, чтобы вычислить total.total. Что-то вроде этого (я создал только триггеры вставки и обновления для term1, чтобы сократить размер ответа)
drop trigger if exists trigger_after_term1_insert;
drop trigger if exists trigger_before_term1_insert;
drop trigger if exists trigger_after_term1_update;
drop trigger if exists trigger_before_term1_update;
delimiter $$
create trigger trigger_term1_before_insert before insert on term1
for each row
begin
insert into debug_table(msg) values (concat('before insert:',new.subject1_score + new.subject2_score + new.subject3_score));
set new.total = new.subject1_score + new.subject2_score + new.subject3_score; #you may need coalesce here
end $$
delimiter $$
create trigger trigger_term1_before_update before update on term1
for each row
begin
insert into debug_table(msg) values (concat('before update:',new.subject1_score + new.subject2_score + new.subject3_score));
set new.total = new.subject1_score + new.subject2_score + new.subject3_score; #you may need coalesce here
end $$
delimiter $$
create trigger trigger_term1_after_insert after insert on term1
for each row
begin
insert into debug_table(msg) values ('after insert');
if not exists (select 1 from overall o where o.studentid = new.studentid) then
insert into debug_table(msg) values ('after insert Not exists');
insert into overall(studentid,total)
select studentid,sum(tot)
from
(
select new.studentid,new.subject1_score + new.subject2_score + new.subject3_score tot
union all
select studentid,subject1_score + subject2_score + subject3_score from term2 #amend as required
union all
select studentid,subject1_score + subject2_score + subject3_score from term3 #amend as required
union all
select studentid,subject1_score + subject2_score + subject3_score from term4 #amend as required
) b
group by studentid;
end if;
end $$
delimiter $$
create trigger trigger_term1_after_update after update on term1
for each row
begin
insert into debug_table(msg) values ('after update');
if exists (select 1 from overall o where o.studentid = new.studentid) then
insert into debug_table(msg) values ('after update exists');
update overall
join (select studentid,sum(tot) tot
from
(
select new.studentid,new.subject1_score + new.subject2_score + new.subject3_score tot
union all
select studentid,subject1_score + subject2_score + subject3_score from term2 #amend as required
union all
select studentid,subject1_score + subject2_score + subject3_score from term3 #amend as required
union all
select studentid,subject1_score + subject2_score + subject3_score from term4 #amend as required
) a
group by studentid
) s
on s.studentid = overall.studentid
set overall.total = s.tot;
else
insert into debug_table(msg) values ('after update Not exists');
insert into overall(studentid,total)
select studentid,sum(tot)
from
(
select new.studentid,new.subject1_score + new.subject2_score + new.subject3_score tot
union all
select studentid,subject1_score + subject2_score + subject3_score from term2 #amend as required
union all
select studentid,subject1_score + subject2_score + subject3_score from term3 #amend as required
union all
select studentid,subject1_score + subject2_score + subject3_score from term4 #amend as required
) b
group by studentid;
end if;
end $$
delimiter ;
Примечание 1) debug_table используется для помощи в отладке 2) studentid является первичным ключом для всех таблиц
Вы можете обойтись без триггеров before, если ваша версия mysql поддерживает сгенерированные столбцы, НО вам действительно не следует хранить данные, которые можно легко вычислить.
ЕСЛИ ваш db был нормализован, тогда весь этот код исчезает. Рассмотрим таблицу studentid, term, subject, subject_score