代码之家  ›  专栏  ›  技术社区  ›  Andrew

MySQL:如何对一个组求和()timediff()?

  •  14
  • Andrew  · 技术社区  · 14 年前

    所以我得到了一组这样的结果:

    SELECT User_ID, StartTime, EndTime, TIMEDIFF(EndTime, StartTime) AS TimeDiff
    FROM MyTable
    
    ------------------------------------------------------------------
    | User_ID |       StartTime     |         EndTime     | TimeDiff |
    ------------------------------------------------------------------
    |    1    | 2010-11-05 08:00:00 | 2010-11-05 09:00:00 | 01:00:00 |
    ------------------------------------------------------------------
    |    1    | 2010-11-05 09:00:00 | 2010-11-05 10:00:00 | 01:00:00 |
    ------------------------------------------------------------------
    |    2    | 2010-11-05 06:30:00 | 2010-11-05 07:00:00 | 00:30:00 |
    ------------------------------------------------------------------
    |    2    | 2010-11-05 07:00:00 | 2010-11-05 09:00:00 | 02:00:00 |
    ------------------------------------------------------------------
    |    2    | 2010-11-05 09:00:00 | 2010-11-05 10:00:00 | 01:00:00 |
    ------------------------------------------------------------------
    

    现在我需要将结果分组 User_ID SUM() TimeDIFF。如果我添加一个 GROUP BY 条款,它没有 () 时间差异(我不希望如此)。我怎么能 () 每个用户的时间差?

    5 回复  |  直到 6 年前
        1
  •  32
  •   Nizam    11 年前

    用途:

      SELECT t.user_id,       
             SEC_TO_TIME(SUM(TIME_TO_SEC(t.endtime) - TIME_TO_SEC(t.starttime))) AS timediff
        FROM MYTABLE t
    GROUP BY t.user_id
    

    步骤:

    1. 使用 TIME_TO_SEC 将数学运算的时间转换为秒
    2. 把差额加起来
    3. 使用 SEC_TO_TIME 将秒转换回时间

    根据样本数据,我建议:

      SELECT t.user_id,       
             TIMEDIFF(MIN(t.startdate), MAX(t.enddate)) AS timediff
        FROM MYTABLE t
    GROUP BY t.user_id   
    

    注意:如果您使用的是日期时间,则此代码中有一个错误。 时间转换为秒只转换时间段,这样你最终会得到大的 如果时钟超过午夜,则为负。改用unix_timestamp 做算术题。秒到秒时间的最大值也大于 3020399秒,例如,如果您 看到这个值838:59:59你已经达到最大值,可能只需要 除以3600只显示小时数。

        2
  •  2
  •   Wrikken    14 年前

    阿法克,你唯一的选择是 UNIX_TIMESTAMP 然后做一些整数计算,用一个随机日期(我选择了2000-01-01)代替没有日期的时间列。

    SELECT TIMEDIFF(
        DATE_ADD('2000-01-01 00:00:00',
           INTERVAL 
           SUM(UNIX_TIMESTAMP(CONCAT('2000-01-01 ',TimeDiff)) - UNIX_TIMESTAMP('2000-01-01 00:00:00')
           SECOND),
        '2000-01-01 00:00:00')
    FROM MyTable;
    

    因为它可能 似乎 你可以 SUM 时间列,但实际上它们将被强制转换为不符合时间规范的讨厌的整数或浮点数(尝试使用分钟数总和>60,您将看到我的意思)。


    对于那些声称你可以 时间栏:

    mysql> create table timetest(a TIME);
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> INSERT INTO timetest VALUES ('02:00'),('03:00');
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> SELECT SUM(a) FROM timetest;
    +--------+
    | SUM(a) |
    +--------+
    |  50000 |
    +--------+
    1 row in set (0.00 sec)
    
    mysql> SELECT TIME(SUM(a)) FROM timetest;
    +--------------+
    | TIME(SUM(a)) |
    +--------------+
    | 05:00:00     |
    +--------------+
    1 row in set (0.00 sec)
    
    mysql> -- seems ok, but wait
    mysql> INSERT INTO timetest VALUES ('02:30');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> SELECT TIME(SUM(a)) FROM timetest;
    +--------------+
    | TIME(SUM(a)) |
    +--------------+
    | 07:30:00     |
    +--------------+
    1 row in set (0.00 sec)
    
    mysql> -- and now, oh ye unbelievers:
    mysql> INSERT INTO timetest VALUES ('01:40');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> SELECT TIME(SUM(a)) FROM timetest;
    +--------------+
    | TIME(SUM(a)) |
    +--------------+
    | NULL         |
    +--------------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> -- why is that? because it uses integer arithmetic, not time - arithmetic:
    mysql> SELECT SUM(a) FROM timetest;
    +--------+
    | SUM(a) |
    +--------+
    |  87000 |
    +--------+
    1 row in set (0.00 sec)
    
    mysql> -- that cannot be cast to time
    
        3
  •  1
  •   a1ex07    14 年前

    对你有用吗?

    select user_id,time(sum(timediff(endtime,starttime)))as timediff
    从mytable group by user_id

    从mytable group by user_id

        4
  •  0
  •   David L    8 年前

    我建议你用 TO_SECONDS 而是:

    SELECT t.user_id,       
             SEC_TO_TIME(SUM(TO_SECONDS(t.endtime) - TO_SECONDS(t.starttime))) AS timediff
        FROM MYTABLE t
    GROUP BY t.user_id
    
        5
  •  0
  •   Bobbi Lusic    6 年前

    这在时间跟踪应用程序中对我很有效。简言之,我将所有间隔转换为秒,将它们相加,然后转换回时间格式。 我是个初学者,所以请原谅代码中的任何笨拙之处。我总是欢迎反馈。

    创建表时间段(segment_id int not null auto_increment primary key,sign_in datetime,sign_out datetime,seconds int not null,display time not null,user_id int);

    更新 time_segments 集合 Seconds =时间-秒( sign_in , sign_out );

    更新 时间段 集合 Display =秒到秒时间(秒);

    插入时间段(签到、签退、用户ID)值(‘2019-03-12 14:01:00’,‘2019-03-12 16:45:00’,1),……;

    mysql>从时间段中选择*

    |段标识标识标识秒显示|

    | 1 2019-03-12 14:01:00 2019-03-12 16:45:00 9840 02:44:00|

    mysql>从时间段中选择sec_to_time(sum(seconds))作为“PayPeriod hours”;

    |付薪期间小时数| +-------------+ | 49点29分|