Reputation: 105
Currently trying to find a way to do the following inside some form of loop (preferably without a performance hit on database).
I have 3 tables user_hours
, user_calendar
and hours_statistics
. I need to first do:
SELECT user_calendar.date_start,
user_calendar.opportunity_id,
user_hours.user_id,
user_hours.agreed_hours,
user_hours.completed_hours,
user_hours.hours_committed
FROM user_calendar
JOIN user_hours
ON user_calendar.user_calendar_id = user_hours.user_calendar_id
WHERE user_calendar.date_start = CURRENT_DATE()
AND user_hours.completed_hours IS NULL
AND user_hours.hours_committed = 'accepted'
This query could return like the following:
https://i.sstatic.net/FAV61.png
So for each opportunity_id and user_id returned i'd like to then do:
UPDATE user_hours
SET completed_hours = agreed_hours,
hours_committed = 'completed'
WHERE opportunity_id = {opportunity_id}
AND user_id = {user_id}
AND hours_committed = 'accepted'
AND completed_hours IS NULL
Note that {opportunity_id} and {user_id} would need to be looped at this point (see screenshot) because we need to go through each user on each opportunity.
Then for each updated record i'd need to then get the total hours like:
// Get hours they have done to send to statistics data table
SELECT sum(completed_hours) FROM user_hours WHERE user_id = {user_id} AND opportunity_id = {opportunity_id}
// Get the completed hours total somehow as a variable
$completed_hours = (from result above)
// Commit stats
UPDATE hours_statistics SET completed_hours = (completed_hours+$completed_hours)
WHERE user_id = {user_id} AND opportunity_id = {opportunity_id}
Could anyone help write this as a procedure or a trigger of some kind or help me in the right direction to get a starting point for looping over this stuff? Manually the querying works, just need to be looped / automatic for a stats update to run.
Upvotes: 1
Views: 114
Reputation: 125865
You can create a trigger to update hours_statistics
whenever user_hours
is updated (you may also want to add similar triggers for INSERT
and DELETE
operations, depending on your application logic).
Assuming that a UNIQUE
key has been defined on hours_statistics.(user_id, opportunity_id)
one can use INSERT ... ON DUPLICATE KEY UPDATE
within the trigger:
CREATE TRIGGER foo AFTER UPDATE ON user_hours FOR EACH ROW
INSERT INTO hours_statistics (user_id, opportunity_id, completed_hours) VALUES
(OLD.user_id, OLD.opportunity_id, -OLD.completed_hours),
(NEW.user_id, NEW.opportunity_id, +NEW.completed_hours)
ON DUPLICATE KEY UPDATE
completed_hours = completed_hours + VALUES(completed_hours);
Then you can use a single UPDATE
statement (using the multiple-table syntax to join user_hours
with user_calendar
) to perform all of the updates on user_hours
in one go, which will cause the above trigger to update hours_statistics
as desired:
UPDATE user_hours JOIN user_calendar USING (user_calendar_id, opportunity_id)
SET user_hours.completed_hours = agreed_hours,
user_hours.hours_committed = 'completed'
WHERE user_hours.hours_committed = 'accepted'
AND user_hours.completed_hours IS NULL
AND user_calendar.date_start = CURRENT_DATE();
Upvotes: 2