【问题标题】:Time Difference between per person between consecutive rows连续行之间每人的时间差
【发布时间】:2019-10-14 10:46:11
【问题描述】:

我有一些数据(广义上)由以下字段组成:

Person  TaskID   Start_time                      End_time
Alpha   1       'Wed, 18 Oct 2017 10:10:03 GMT' 'Wed. 18 Oct 2017 10:10:36 GMT'
Alpha   2       'Wed, 18 Oct 2017 10:11:16 GMT' 'Wed, 18 Oct 2017 10:11:28 GMT'
Beta    1       'Wed, 18 Oct 2017 10:12:03 GMT' 'Wed, 18 Oct 2017 10:12:49 GMT'
Alpha   3       'Wed, 18 Oct 2017 10:12:03 GMT' 'Wed, 18 Oct 2017 10:13:13 GMT'
Gamma   1       'Fri, 27 Oct 2017 22:57:12 GMT' 'Sat, 28 Oct 2017 02:00:54 GMT'
Beta    2       'Wed, 18 Oct 2017 10:13:40 GMT' 'Wed, 18 Oct 2017 10:14:03 GMT'

对于这个数据,我需要的输出是这样的:

Person  TaskID Time_between_attempts
Alpha   1      NULL      ['Wed, 18 Oct 2017 10:10:03 GMT' - NULL]
Alpha   2      0:00:40   ['Wed, 18 Oct 2017 10:11:16 GMT' -'Wed, 18 Oct 2017 10:10:36 GMT']
Beta    1      NULL      ['Wed, 18 Oct 2017 10:12:03 GMT' - NULL]
Alpha   3      0:00:35   ['Wed, 18 Oct 2017 10:12:03 GMT' -'Wed, 18 Oct 2017 10:11:28 GMT']
Gamma   1      NULL      ['Fri, 27 Oct 2017 22:57:12 GMT' - NULL]
Beta    2      0:00:51   ['Wed, 18 Oct 2017 10:13:40 GMT' -'Wed, 18 Oct 2017 10:12:49 GMT']

我的要求如下:

一个。对于给定的人(Alpha、Beta 或 Gamma),变量“time_between_attempts”的第一次出现将为零/NULL - 在示例中我将其显示为 NULL。

b.第二次(以及随后的),同一个人出现将有一个非 NULL 或非零的“time_between_attempts”。这个变量是通过取上一个任务的结束时间和下一个任务的开始时间之间的差来计算的。

在这方面我有以下问题:

  1. 如何编写可以帮助我实现所需输出的 ​​SQL 脚本?

请注意,TaskID 写成整数只是为了简化。在原始数据中,TaskID 很复杂,由不连续的字符串组成:

'q:1392763916495:441',
'q:1392763916495:436'

对此的任何建议将不胜感激。

【问题讨论】:

    标签: mysql sql split strsplit date-difference


    【解决方案1】:

    使用 self Join() 方法。

        SELECT a.person, 
                a.taskid, 
                TIMEDIFF (DATE_FORMAT(STR_TO_DATE(a.Start_time, '%a, %d %b %Y %H:%i:%s'), '%Y-%m-%d %H:%i:%s') ,DATE_FORMAT(STR_TO_DATE(b.End_time, '%a, %d %b %Y %H:%i:%s'), '%Y-%m-%d %H:%i:%s') ) as Time_between_attempts,
                a.Start_time,
                b.End_time
    
            FROM   test a 
                LEFT JOIN test b 
                        ON a.person = b.person 
                            AND a.taskid = b.taskid + 1 
            ORDER  BY 1, 2; 
    

    但这会忽略时区。

    【讨论】:

    • 感谢您发布解决方案,我已经更新了我的问题,您能否进一步帮助我?
    • 能否详细说明这段代码的工作原理?我很难理解 Join 部分以及您在 1,2 之前订购的地点/原因?
    【解决方案2】:

    这回答了问题的原始版本。

    您可以使用lag()timestampdiff() 进行计算。假设您的值是真实的日期/时间或时间戳,那么您可以轻松地以秒为单位计算值:

    select t.*,
           timestampdiff(start_time,
                         lag(end_time) over (partition by person_id order by start_time)
                         seconds
                        )
    from t;
    

    如果值存储为字符串,请修复数据!同时,您可以在函数中使用str_to_date()

    将其作为时间值:

    select t.*,
           (time(0) +
            interval timestampdiff(start_time,
                                   lag(end_time) over (partition by person_id order by start_time)
                                   seconds
                                  ) second
           )
    from t;
    

    【讨论】:

    • @Gordon 我无法运行此查询。有一条错误消息:“选择”在此服务器版本的此位置没有有效输入,期望:'(',WITH.....我正在使用mysql workbench 8.0。
    • @Sadiaz 。 . .此答案中只有一个select,它位于查询的开头。应该没有问题。
    • @GordonLinoff ,由于某种原因,代码无法正常工作。我收到以下错误消息:错误代码:1064。您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 2 行的 'Start_Time, lag(End_Time) over (partition by userId order by Start_Time) ' 附近使用正确的语法 实际代码是: select timestampdiff(Start_Time, lag(End_Time ) 从 int_stellar t 开始 (按 userId order by Start_Time) seconds );
    • @Sadiaz 。 . .您使用的是哪个版本的 MySQL?工作台版本不相关。
    • 这是 MySQL 服务器 5.7
    猜你喜欢
    • 2020-10-21
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 2012-04-17
    • 2023-02-26
    • 1970-01-01
    相关资源
    最近更新 更多