通过mysql表数据循环

通过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:

我有一个包含数据的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:(自动增量列)
  • mailid:(电子邮件的唯一ID)
  • currentstatus:(邮件的当前状态)
  • assignedto:(电子邮件分配给的用户名)
  • assignedtime:(分配电子邮件的日期和时间)
  • logtime:(插入行的日期和时间,即当前状态的日期和时间)
id 4338和5731分别是mailid 14928和15710的第一行,这些id的最后一行是16300和16291,它们的当前状态始终为“已回复”

这里,我需要输出

(日志时间4352-日志时间4338)+(日志时间16300-日志时间 16297)

这将提供user1在mailid 14928上花费的时间

这里的共同点是:

  • 最后一行的列currentstatus将始终为“已回复”
  • 用currentstatus中前面的“assigned”减去的每一行
  • 表格如何更新:

    这是电子邮件管理解决方案的一部分,在该解决方案中,电子邮件被分配给用户,用户可以回复电子邮件,也可以将其放入后续并稍后回复

    在以下两种情况下,都为用户分配了一封电子邮件(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;
    
        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,我已将其添加到我的问题中!谢谢在您的帮助下,我能够优化查询