如何使用MySQL合并日期和时间的连续行

问题描述

我有一张下表(视图)

+-------+-------------+-------------+
| Data  |    Date     |    Time     |
+-------+-------------+-------------+
| Data1 |  2020-08-19 |    13:00:00 |
| Data1 |  2020-08-19 |    13:30:00 |
| Data1 |  2020-08-19 |    14:00:00 |
| Data1 |  2020-08-21 |    07:00:00 |
| Data1 |  2020-08-21 |    07:30:00 |
| Data2 |  2020-08-20 |    08:00:00 |
| Data2 |  2020-08-20 |    08:30:00 |
+-------+-------------+-------------+

我正在尝试找到一种创建SQL语句的方法,该方法将执行以下操作:合并具有连续日期和时间(间隔30分钟)的数据

从基本的SQL到早期的中级SQL能力,我无法正确使用GROUP BY。期待答案或方向。 再次非常感谢

结果应为:

+-------+-------------+-------------+
| Data  |     Date    |    Time     |
+-------+-------------+-------------+
| Data1 |  2020-08-19 |    13:00:00 |
| Data1 |  2020-08-21 |    07:00:00 |
| Data2 |  2020-08-20 |    08:00:00 |
+-------+-------------+-------------+

解决方法

您可以使用窗口功能。这个想法是使用一个窗口总和来创建相邻记录的组,每次两个连续记录之间的差异超过30分钟时,窗口总和就会递增。

select data,min(dt) start_dt,max(dt) end_dt,count(*) cnt
from (
    select
        t.*,sum(lag_dt is not null and dt > lag_dt + interval 30 minute)
            over(partition by data order by dt) grp
    from (
        select
            t.*,lag(dt) over(partition by data order by dt) lag_dt
        from (
            select t.*,concat(date,' ',time) dt 
            from mytable t
        ) t
    ) t
) t
group by data,grp
order by min(dt)

请注意,将日期和时间存储在两个单独的列中不是一个好习惯;我添加了一层额外的嵌套来生成datetime值。

我们可以使用日期算法消除一级嵌套(此处的间隔必须恰好是30分钟):

select data,count(*) cnt
from (
    select 
        t.*,row_number() over(partition by data order by dt) rn
    from (
        select t.*,time) dt 
        from mytable t
    ) t
) t
group by data,dt - interval (rn * 30) minute
order by min(dt)
,

具有LAG()窗口功能:

select Data,Date,Time
from (
  select *,concat(Date,Time) - interval 30 minute <= 
      lag(concat(Date,Time)) over (partition by Data order by Date,Time) flag
  from tablename  
) t
where coalesce(flag,0) = 0
order by Data,Time

请参见demo
结果:

> Data  | Date       | Time    
> :---- | :--------- | :-------
> Data1 | 2020-08-19 | 13:00:00
> Data1 | 2020-08-21 | 07:00:00
> Data2 | 2020-08-20 | 08:00:00
,

针对postgres更新

select Data,Date+ Time - interval '00:30' <= 
      lag(Date+ Time,1) over (partition by Data order by Date+Time) flag
  from tablename  
) T
where flag is null or  flag is false
order by Data,Time

Demo

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...