GROUP_CONCAT根据分组行的其他字段的值

问题描述

我有一个列如下的表:

| id | name  | entrance | eName  |
|----|-------|----------|--------|
| 1  | user1 | 5:10     | enter1 |
| 2  | user2 | 2:15     | enter1 |
| 3  | user3 | 3:05     | enter3 |
| 1  | user1 | 5:12     | enter2 |
| 1  | user1 | 7:30     | enter2 |

我想做的是根据eName字段的值的不同对entrance进行分组,如果值之间的差异为(2),则将它们分组在其他位置,将其返回为新行? >

所需的输出如下:

| id | name  |
|----|-------|--------       |
| 1  | user1 | enter1,enter2|
| 2  | user2 | enter1        |
| 3  | user3 | enter3        |
| 1  | user1 | enter2        |

解决方法

我认为这是一个“岛与岛”问题,其中岛屿由同一用户的相邻入口组成,最大间隔为2分钟。

这是一种使用窗口函数的方法(在MySQL 8.0中可用):

select id,name,group_concat(ename order by entrance) enames,count(*) cnt_entrances,min(entrance) first_entrance,max(entrance) last_entrance
from (
    select t.*,sum(entrance > lag_entrance + interval 2 minute) over(partition by id,name order by entrance) grp
    from (
        select t.*,lag(entrance,1,entrance) over(partition by id,name order by entrance) lag_entrance
        from mytable t
    ) t
) t
group by id,grp

lag()为您提供“上一个”入口的日期,然后我们使用累积的sum(),每当满足2分钟以上的间隔时,该累积值就会递增,以定义组。我在结果集中添加了更多列,以使其更易于理解。

Demo on DB Fiddlde

id | name  | enames        | cnt_entrances | first_entrance | last_entrance
-: | :---- | :------------ | ------------: | :------------- | :------------
 1 | user1 | enter1,enter2 |             2 | 05:10:00       | 05:12:00     
 1 | user1 | enter2        |             1 | 07:30:00       | 07:30:00     
 2 | user2 | enter1        |             1 | 02:15:00       | 02:15:00     
 3 | user3 | enter3        |             1 | 03:05:00       | 03:05:00