如何通过多列将SQL中的连续行组合在一起

时间:2018-04-19 23:29:43

标签: sql oracle group-by

我在查询中有行返回类似的内容:

Date        User    Time    Location    Service     Count
1/1/2018    Nick    12:00   Location A  X           1
1/1/2018    Nick    12:01   Location A  Y           1
1/1/2018    John    12:02   Location B  Z           1
1/1/2018    Harry   12:03   Location A  X           1
1/1/2018    Harry   12:04   Location A  X           1
1/1/2018    Harry   12:05   Location B  Y           1
1/1/2018    Harry   12:06   Location B  X           1
1/1/2018    Nick    12:07   Location A  X           1
1/1/2018    Nick    12:08   Location A  Y           1

其中查询返回用户访问的位置以及从该位置完成的选择计数。结果按用户和时间升序排序。我需要将它分组到具有相同用户和位置的CONSECUTIVE行与服务列中的Sum of Count列和逗号分隔的唯一值列表进行分组,最终结果返回如下内容:

Date        User    Start Time  End Time    Location    Service Count
1/1/2018    Nick    12:00       12:01       Location A  X,Y     2
1/1/2018    John    12:02       12:02       Location B  Z       1
1/1/2018    Harry   12:03       12:04       Location A  X       2
1/1/2018    Harry   12:05       12:06       Location B  X,Y     2
1/1/2018    Nick    12:07       12:08       Location A  X,Y     2

我不知道从哪里开始。也许滞后或分区条款?希望SQL大师可以在这里提供帮助...

2 个答案:

答案 0 :(得分:1)

这是一个空白和岛屿问题。解决它的一种方法是使用mysqli_fetch_array

row_number()

解释这是如何工作有点棘手。我的建议是运行子查询,您将看到行号的差异如何定义您要查找的组。

答案 1 :(得分:1)

使用lag获取上一行的用户和位置值。然后,只要用户和位置发生更改,就使用运行总和生成新组。最后汇总分类的组,用户,位置和日期。

select Date, User, min(Time) as start_time,max(time) as end_time, Location,
listagg(Service, ',') within group (order by Service),
count(*) as cnt
from (select Date, User, Time, Location, 
      sum(case when prev_location=location and prev_user=user then 0 else 1 end) over(order by date,time) as grp
      from (select Date, User, Time, Location,
            lag(Location) over(order by date,time) as prev_location,
            lag(User) over(order by date,time) as prev_user,
            from t
           ) t
      ) t
group by Date, User, Location, grp;