Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL组从季度到周期_Mysql_Sql_Date_Window Functions_Gaps And Islands - Fatal编程技术网

MySQL组从季度到周期

MySQL组从季度到周期,mysql,sql,date,window-functions,gaps-and-islands,Mysql,Sql,Date,Window Functions,Gaps And Islands,我有一张这样的桌子: Person smallint(5) act_time datetime 1 2020-05-29 07:00:00 1 2020-05-29 07:15:00 1 2020-05-29 07:30:00 2 2020-05-29 07:15:00 2 2020-05-29 07:30:00 1 2020-05-29 10:30:00 1 2020-05-29 10:45:00 上表是一个例子,有两个不同的人,每个季度都有一行他们在工作 在M

我有一张这样的桌子:

Person smallint(5)  act_time datetime
1   2020-05-29 07:00:00
1   2020-05-29 07:15:00
1   2020-05-29 07:30:00
2   2020-05-29 07:15:00
2   2020-05-29 07:30:00
1   2020-05-29 10:30:00
1   2020-05-29 10:45:00
上表是一个例子,有两个不同的人,每个季度都有一行他们在工作

在MySQL中,将这个表转换为另一个表的最佳方式是什么?在这个表中,有一列表示person,一列表示start,一列表示stop

结果是:

Person  Start   Stop
1   2020-05-29 07:00:00   2020-05-29 07:45:00
2   2020-05-29 07:15:00   2020-05-29 07:45:00
1   2020-05-29 10:30:00   2020-05-29 11:00:00
我尝试过使用左连接到同一个原始表,但不起作用

谢谢 谢谢你的回复。我现在已经用上面的表格试过了——不幸的是,它没有给出那个结果。。。 我的sql字符串是:

select person,min(act_time) start_date,max(act_time) end_date from (select t.*,row_number() over(order by act_time) rn1,row_number() over(partition by person order by act_time) rn2 from test t) t group by person, rn1 - rn2 order by min(act_time)

But the result it generates is:
1 29-05-2020 07:00:00 29-05-2020 07:15:00
2 29-05-2020 07:15:00 29-05-2020 07:15:00
1 29-05-2020 07:30:00 29-05-2020 07:30:00
2 29-05-2020 07:30:00 29-05-2020 07:30:00
1 29-05-2020 10:30:00 29-05-2020 10:45:00

结果应该是3行。因此,当与同一个人的两行之间的间隔超过15分钟时,应该创建一个新行。

这是一个间隔和孤岛问题。您可以使用MySQL 8.0中提供的窗口函数来解决此问题:

select 
    person,
    min(act_date) start_date,
    max(act_date) end_date
from (
    select
        t.*,
        sum(act_date <> lag_act_date + interval 15 minute)
            over(partition by person order by act_date) grp
    from (
        select 
            t.*,
            lag(act_date) 
                over(partition by person order by act_date) lag_act_date
        from mytable t
    ) t
) t
group by person, grp
order by min(act_date)

其思想是使用累积和来构建相邻记录的组:每当间隔不到15分钟时,总和就会增加。

这是一个间隔和孤岛问题。您可以使用MySQL 8.0中提供的窗口函数来解决此问题:

select 
    person,
    min(act_date) start_date,
    max(act_date) end_date
from (
    select
        t.*,
        sum(act_date <> lag_act_date + interval 15 minute)
            over(partition by person order by act_date) grp
    from (
        select 
            t.*,
            lag(act_date) 
                over(partition by person order by act_date) lag_act_date
        from mytable t
    ) t
) t
group by person, grp
order by min(act_date)

其思想是使用累积和来构建相邻记录的组:每当间隔不到15分钟时,总和就会增加。

这是一个间隔和孤岛问题。我不确定为什么GMB的解决方案不起作用,但这应该:

select person, min(act_date) as start_date,
       max(act_date) + interval 15 minute as end_date
from (select t.*,
             sum(case when prev_act_date >= act_date - interval 15 minute then 0 else 1 end) over
                 (partition by person order by act_date) as grp
      from (select t.*,
                   lag(act_date) over (partition by person order by act_date) as prev_act_date
            from t
           ) t
     ) t
group by person, grp
order by min(act_date)

这是一个缺口和孤岛问题。我不确定为什么GMB的解决方案不起作用,但这应该:

select person, min(act_date) as start_date,
       max(act_date) + interval 15 minute as end_date
from (select t.*,
             sum(case when prev_act_date >= act_date - interval 15 minute then 0 else 1 end) over
                 (partition by person order by act_date) as grp
      from (select t.*,
                   lag(act_date) over (partition by person order by act_date) as prev_act_date
            from t
           ) t
     ) t
group by person, grp
order by min(act_date)

虽然我们可能无法提供“最佳”方式,但如果您提供适当的DDL,或许我们可以向您展示“最佳”方式。请看,虽然我们可能无法提供“最佳”方式,但如果您提供适当的DDL,也许我们可以向您展示“最佳”方式。谢谢你的回复。不幸的是,它没有返回期望的结果。。。我已经在问题中添加了它返回的结果。谢谢你的回答。不幸的是,它没有返回期望的结果。。。我已经在问题中添加了它返回的结果。这个字符串成功了。谢谢你的帮助:-这根绳子成功了。感谢您的帮助:-