如何使用 SQL sum 函数在不同的 MySQL 表中添加具有相应主键的值?
Posted
技术标签:
【中文标题】如何使用 SQL sum 函数在不同的 MySQL 表中添加具有相应主键的值?【英文标题】:How do I use the SQL sum function to add values in different MySQL tables with the corresponding Primary Key? 【发布时间】:2020-08-05 06:33:12 【问题描述】:我在 mysql 中创建了五个不同的表,其中包含学生记录。每个表基本上都有统一的列名。 StudentID、Subject1_Score、Subject2_Score、Subject3_Score、Total_Score。这五个表是Term1、Term2、Term3、Term4和overall。
我想要做的是当我将值插入 Term1、Term2、Term3 和 Term4 时,每列分数的总和,Subject1_Score、Subject2_Score、Subject3_Score、Total_Score必须自动计算并放置在 overall 表的相应列中。下面是我的代码。当我将分数插入 Term1 表时,我正在尝试更新 overall 表。它目前正在做的是获取 Total_Score 列的总和。我希望它获取 Term1 中 Total_Score 的值,并将其添加到 overall 中 Total_Score 的值中,然后然后将其放入 overall 作为更新后的当前值。下面是我的代码。请帮助我实现我想做的事情。
SELECT SUM( Total_Score )
FROM (
SELECT SUM( Total_Score ) AS Total_Score
FROM Term1
UNION ALL
SELECT SUM( Total_Score ) AS Total_Score
FROM overall
) AS ALIAS;
【问题讨论】:
这个问题让我很困惑:( 对不起。我将再次简化我的问题。 您是否能够以更规范的方式重新设计您的数据库? 为什么你有5个相同的表?并查看meta.***.com/questions/333952/… 修复你的数据模型!不要试图让损坏的数据模型工作。您不应将一个实体分布在五个表中。 【参考方案1】:您当前的设计尚未标准化,这意味着您需要付出很多努力才能实现您想要的。
对于每个术语表,在插入触发器之前和之后创建、更新触发器之前和之后以及删除触发器之后,您可以在其中解析所有表以计算总体总数。像这样的东西(我只为 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 是所有表的主键
如果你的 mysql 版本支持生成的列,你可以省略之前的触发器,但你真的不应该存储可以轻松计算的数据。
如果您的数据库被规范化,那么所有这些代码都会消失。 考虑一张桌子 studentid,term,subject,subject_score
【讨论】:
以上是关于如何使用 SQL sum 函数在不同的 MySQL 表中添加具有相应主键的值?的主要内容,如果未能解决你的问题,请参考以下文章
使用函数 SUM() 和 Group by 将 Mysql 查询转换为 SQL 查询