I am currently trying to create a database where the user will complete a series of activities, and their score from each activity will be stored in an ‘ActivityLog’ table, here is the current format:
My actual question is when I enter a new record into this table, how would I check whether their score is their best score for that specific activity? I will need to ensure that I am checking the high score for this correct activity, as well as the correct user.
The desired output will look something similar to this (user_id and activity_id will not be null):
The improvement
column is equal to true when the user’s score is greater than their highest score for that specific game, thus creating a new improvement. The logic here must only compare the highest score that this specific user has achieved on this specific activity. I am unsure whether the best approach would be using a trigger to automatically check this upon a database insert?
The reason I am storing these improvements is because I am hoping to retrieve the amount of records where the improvement is equal to true, and visualize these in a graph.
Here is the trigger I’ve got so far:
/* Improvements Trigger */ DELIMITER // CREATE TRIGGER checkImprovement AFTER INSERT ON ActivityLog FOR EACH ROW BEGIN DECLARE hs int; SELECT hs = MAX(score) WHERE user_id = NEW.user_id AND activity_name = NEW.activity_name; IF(NEW.score > hs) UPDATE ActivityLog SET improvement = 1 WHERE log_id = NEW.log_id ELSE UPDATE ActivityLog SET improvement = 0 WHERE log_id = NEW.log_id END // DELIMITER ;
However this code is not currently working and provides me with an error:
‘#1064 – You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘WHERE user_id = NEW.user_id AND activity_name = NEW.activity_name;’
I’m sure there’s a lot to work on here, but I would appreciate a brief explanation of how to approach this!
Advertisement
Answer
You have a few syntax errors.
You need to use SET
to assign the result of a query to a variable (or you can use SELECT ... INTO variable
).
You need THEN
in the IF
statement, and you need ;
at the end of each statement in the IF/THEN/ELSE/
block. But you don’t really need IF
, since the value of a condition is either 1
or 0
depending on whether it’s true or false.
You’re missing the FROM
clause in the query that gets MAX(score)
. I’ve used userTable
below as a placeholder.
You’re updating ALL rows for all users in with the same activity, since you don’t have user_id
in the WHERE
clauses, nor does it specify a particular log row for the user. I think what you really want to do is set the improvement
column in the new row that’s being inserted, not update existing rows. So you should use a BEFORE INSERT
trigger that sets NEW.improvement
.
DELIMITER // CREATE TRIGGER checkImprovement BEFORE INSERT ON ActivityLog FOR EACH ROW SET NEW.improvement = NEW.score > ( SELECT MAX(score) FROM ActivityLog WHERE user_id = NEW.user_id AND activity_name = NEW.activity_name); // DELIMITER ;
You could also combine all this into a single query:
FOR EACH ROW UPDATE ActivityLog SET improvement = (SELECT MAX(score)