Reputation: 133
I have student table and score table and subject table. Student table has 'student_id' and 'avg_score'. Subject table has 'subject_name' and 'subject_id'. Score has 'subject_id','student_id' and 'score' as decimal. I wrote this trigger to calculate the avg score. How can I get exactly score of each student with each subject name and calculate the average score?
CREATE TRIGGER caculateAVG ON dbo.dbo_score
AFTER INSERT,UPDATE,DELETE AS
BEGIN
DECLARE @Math DECIMAL;
DECLARE @Eng DECIMAL;
DECLARE @Liter DECIMAL;
UPDATE x
SET x.avgScore = (@Eng + @Liter + @Math)/3
FROM dbo.dbo_student x
INNER JOIN dbo.dbo_score c ON c.student_id = x.student_id
INNER JOIN dbo.dbo_subject j ON j.subject_id = c.subject_id
SET @Math = (SELECT s.score FROM dbo.dbo_score s INNER JOIN dbo.dbo_subject j ON
j.subject_id = s.subject_id WHERE UPPER(j.subject_name) LIKE 'math')
SET @Eng = (SELECT s.score FROM dbo.dbo_score s INNER JOIN dbo.dbo_subject j ON
j.subject_id = s.subject_id WHERE UPPER(j.subject_name) LIKE 'eng')
SET @Liter = (SELECT s.score FROM dbo.dbo_score s INNER JOIN dbo.dbo_subject j
ON j.subject_id = s.subject_id WHERE UPPER(j.subject_name) LIKE 'literature')
END
Upvotes: 0
Views: 416
Reputation: 27364
When working with SQL Server (or any relational database for that matter) you want to try and solve all problems using set based logic. So we can carry out the update you are attempting in a single query as follows, where I expect you want to restrict the update to only those students affected by the update using the Inserted
and Deleted
pseudo-tables..
UPDATE x
SET x.avgScore = (
(SELECT sum(s.score) FROM dbo.dbo_score s INNER JOIN dbo.dbo_subject j ON j.subject_id = s.subject_id WHERE j.subject_name = 'eng')
+ (SELECT sum(s.score) FROM dbo.dbo_score s INNER JOIN dbo.dbo_subject j ON j.subject_id = s.subject_id WHERE j.subject_name = 'literature')
+ (SELECT sum(s.score) FROM dbo.dbo_score s INNER JOIN dbo.dbo_subject j ON j.subject_id = s.subject_id WHERE j.subject_name = 'math')
)/3
FROM dbo.dbo_student x
where x.student_id in (select student_id from Inserted union all select student_id from Deleted)
Also there is no need to use like
if you aren't using wildcards in your search term. And there is no need to use upper
because SQL Server is generally case insensitive (and you are comparing it to a lowercase word, which would fail if it was case sensitive).
Upvotes: 1