我有一个带有数据的mysql表'table1'
id mailid currentstatus assignedto assignedtime logtime
4338 14928 assigned user1 4/15/2013 13:44 4/15/2013 13:44
4352 14928 followup user1 4/15/2013 13:44 4/15/2013 13:50
16297 14928 assigned user1 4/15/2013 13:44 4/29/2013 9:52
16300 14928 replied user1 4/15/2013 13:44 4/29/2013 9:55
5731 15710 assigned user2 4/17/2013 10:16 4/17/2013 10:17
5769 15710 followup user2 4/17/2013 10:16 4/17/2013 10:35
16281 15710 assigned user2 4/17/2013 10:16 4/29/2013 9:40
16291 15710 replied user2 4/17/2013 10:16 4/29/2013 9:48
我想知道每个用户花在每个mailid上的时间。
列的说明:
id:(自动递增列)
mail id:(电子邮件的唯一ID)
当前状态:(邮件的当前状态)
assigned to:(电子邮件分配给的用户名)
assignedTime:(电子邮件被分配的日期和时间)
logtime:(行插入的日期和时间,即当前状态的日期和时间)
id 4338和5731分别是mailid 14928和15710的第一行,这些id的最后一行是16300和16291,它们的当前状态始终为“已答复”。
这里,我需要输出
(记录时间4352-记录时间4338)+(记录时间16300-记录时间
16297)
这将为我提供用户1在mailid 14928上花费的时间。
这里常见的是:
最后一行的currentStatus列将始终为“已答复”
在当前状态下用前面的“赋值”减去的每一行
如何更新表:
这是电子邮件管理解决方案的一部分,在该解决方案中,电子邮件被分配给用户,用户可以回复电子邮件,也可以将其放在后续中,稍后再回复。
在以下两种情况下,用户都被分配了一封电子邮件(14928和15710)。这两个用户都将这些电子邮件放在了后面,当他们必须回复这封电子邮件时,这些电子邮件被重新分配,然后被回复。
请帮忙!
所需输出为:
mailid assignedto timespent
14928 user1 00:08:55
15710 user2 00:26:57
到目前为止,我能够编写下面的查询,但是,需要优化这个查询。
SELECT mailid,
assignedto,
sum(st) TimeSpent
FROM
( SELECT b.*,
CASE WHEN b.currentstatus = 'assigned'
THEN TIMESTAMPDIFF(SECOND, b.logtime, (SELECT a.logtime
FROM inbox_log a
WHERE a.mailid = b.mailid
AND a.logtime > b.logtime
ORDER BY a.table1 LIMIT 1))
ELSE 0
END st
FROM table1 b
WHERE logtime >= '2013-04-25') d
GROUP BY mailid,
assignedto;
抱歉,既然遇到了麻烦
http://sqlfiddle.com
对于16000行,此查询大约需要150秒。任何关于如何优化此查询的建议
最佳答案
感谢@chitranjan thakur,我无法优化查询。下面是我创建的函数。
CREATE DEFINER=`root`@`%` FUNCTION <function-name>(mailidparam INT) RETURNS INT(11)
BEGIN
DECLARE bdone,
abc BOOL;
DECLARE mt VARCHAR(150);
DECLARE lt DATETIME;
DECLARE tstart,
tend DATETIME;
DECLARE taht INT;
DECLARE curs CURSOR FOR
SELECT
il.currentstatus,
il.logtime
FROM table1 il
WHERE il.mailid = mailidparam
ORDER BY il.logtime;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = TRUE;
OPEN curs;
SET bDone = FALSE;
SET taht = 0;
SET tend = NULL;
read_loop:
LOOP
FETCH curs INTO mt, lt;
IF bdone THEN
LEAVE read_loop;
END IF;
IF (mt = 'assigned') THEN
SET tstart = lt;
ELSE
SET tend = lt;
SET taht := taht + TIMESTAMPDIFF(SECOND, tstart, tend);
END IF;
END LOOP;
CLOSE curs;
RETURN taht;
END$$
DELIMITER ;
而这个问题
SELECT
*,
get_mailid_aht (il.mailid) aht
FROM
table1 il
WHERE il.currentstatus = 'replied' ;
以前的工作大约需要125秒,但是在实现该功能之后,大约需要108秒,这不是一个很大的成就。
但是,添加mailid、currentstatus和logtime worked的索引
就像魔术一样,现在查询只需3.023秒。
感谢stackoverflow的成员,他们总是在这里提供帮助!