MySQL更新从select和进一步选择和更新

时间:2012-08-26 10:29:12

标签: php mysql stored-procedures event-triggers

目前正试图在某种形式的循环中找到一种方法来执行以下操作(最好不要在数据库上有性能命中)。

我有3个表user_hoursuser_calendarhours_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'

此查询可能会返回如下内容:

http://i.imgur.com/5cJ5v.png

因此,对于每个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} 

任何人都可以帮忙把它写成某种程序或触发器,或者帮助我找到正确的方向来获得循环这个东西的起点吗?手动查询工作,只需要循环/自动运行统计信息更新。

1 个答案:

答案 0 :(得分:2)

您可以创建触发器,以便在hours_statistics更新时更新user_hours(您可能还需要为INSERTDELETE操作添加类似的触发器,具体取决于您的应用程序逻辑)。

假设在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();