通过mysql表数据循环
我有一个包含数据的mysql表“table1”通过mysql表数据循环,mysql,function,select,stored-procedures,Mysql,Function,Select,Stored Procedures,我有一个包含数据的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:
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:(自动增量列)
- mailid:(电子邮件的唯一ID)
- currentstatus:(邮件的当前状态)
- assignedto:(电子邮件分配给的用户名)
- assignedtime:(分配电子邮件的日期和时间)
- logtime:(插入行的日期和时间,即当前状态的日期和时间)
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;
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;
抱歉,因为面临问题,无法制造麻烦
对于16000行,此查询大约需要150秒。任何关于如何优化此查询的建议我已经得到了答案,但是,需要优化此查询
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;
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;
抱歉,因为面临问题,无法制造麻烦
对于16000行,此查询大约需要150秒。任何关于如何优化此查询的建议嘿,您可以使用“函数”进行优化:首先,您需要创建一个函数,该函数将只生成您想要对其执行操作的记录 语法:
CREATE FUNCTION func_name ([func_parameter[,...]]) RETURNS type routine_body
mysql> SELECT hello_world('Earth');
1 row in set (0.00 sec)
示例
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 ;
执行如下操作:
CREATE FUNCTION func_name ([func_parameter[,...]]) RETURNS type routine_body
mysql> SELECT hello_world('Earth');
1 row in set (0.00 sec)
这将花费更少的时间,并且对您有效。多亏了@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 ;
之前的工作通常需要约125秒,但在实现该功能后需要约108秒,这并不是一项伟大的成就
但是,添加mailid、currentstatus和logtime的索引是可行的
就像魔术一样,现在查询只需3.023秒
感谢StackOverflow会员,他们一直在这里帮助我们@Satya,我曾尝试创建一个在各行之间循环的过程,但没有成功……用您正在使用的编程语言如何?@jimy,我正在使用php。事实上,我也在做同样的事情。一旦我得到想要的输出,我就会发布。但是,您有什么建议吗?mailid是否总是分配给同一个用户ID?但是解决方法很混乱。我认为最好重新开始。把这个写在你的问题里。并添加
解释您的查询的结果
,以便我们了解有关执行的更多信息。谢谢@Jocelyn,我已将其添加到我的问题中!谢谢在您的帮助下,我能够优化查询