目前正试图在某种形式的循环中找到一种方法来执行以下操作(最好不要在数据库上有性能命中)。
我有3个表user_hours
,user_calendar
和hours_statistics
。我需要先做:
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'
此查询可能会返回如下内容:
因此,对于每个opportunity_id和user_id返回,我想做:
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
请注意,{opportunity_id}和{user_id}此时需要循环播放(请参阅屏幕截图),因为我们需要在每个机会上浏览每个用户。
然后,对于每个更新的记录,我需要得到总时数,如:
// 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}
任何人都可以帮忙把它写成某种程序或触发器,或者帮助我找到正确的方向来获得循环这个东西的起点吗?手动查询工作,只需要循环/自动运行统计信息更新。
答案 0 :(得分:2)
您可以创建触发器,以便在hours_statistics
更新时更新user_hours
(您可能还需要为INSERT
和DELETE
操作添加类似的触发器,具体取决于您的应用程序逻辑)。
假设在UNIQUE
上定义了hours_statistics.(user_id, opportunity_id)
密钥,可以在触发器中使用INSERT ... ON DUPLICATE KEY UPDATE
:
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);
然后,您可以使用单个UPDATE
语句(使用多表语法将user_hours
加入user_calendar
)以在user_hours
中执行所有更新go,这将导致上述触发器根据需要更新hours_statistics
:
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();