我有一个带有数据的
的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 4338和5731分别是mailid 14928和15710的第一行,这些id的最后一行是16300和16291,它们的currentstatus总是为'replied'。
这里,我需要输出
(logtime为4352 - logtime为4338)+(logtime为16300 - logtime of 16297)
这将为我提供user1在mailid 14928上花费的时间。
这里有什么共同点:
表格如何更新:
这是电子邮件管理解决方案的一部分,其中电子邮件分配给用户,用户可以回复电子邮件或将其放入后续处理并稍后回复。
在以下两种情况下,都为用户分配了一封电子邮件(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
对于16,000行,此查询大约需要150秒。任何建议我如何优化此查询
答案 0 :(得分:2)
感谢@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工作 像魔术一样,现在查询在3.023秒内运行。
感谢StackOverflow成员随时为您提供帮助!
答案 1 :(得分:1)
<强>语法:强>
CREATE FUNCTION func_name ([func_parameter[,...]]) RETURNS type routine_body
示例强>
DELIMITER $$
CREATE FUNCTION hello_world(addressee TEXT)
RETURNS TEXT
LANGUAGE SQL -- This element is optional and will be omitted from subsequent examples
BEGIN
RETURN CONCAT('Hello ', addressee);
END;
$$
DELIMITER ;
执行如下:
mysql> SELECT hello_world('Earth');
1 row in set (0.00 sec)
这将花费更少的时间,并将为你工作。
答案 2 :(得分:0)
我得到了答案,但是,需要优化此查询。
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
对于16,000行,此查询大约需要150秒。任何建议我如何优化此查询