Mysql 如何计算表的连续范围
我有如下表格:Mysql 如何计算表的连续范围,mysql,sql,Mysql,Sql,我有如下表格: VideoId StartTime EndTime EntityMid 1001 1 2 a 1001 2 3 a 1001 7 8 b 1001 10 11 a 1001 11 12 a 1002 4 5 c
VideoId StartTime EndTime EntityMid
1001 1 2 a
1001 2 3 a
1001 7 8 b
1001 10 11 a
1001 11 12 a
1002 4 5 c
1002 7 8 c
我希望得到以下结果:
VideoId EntityMid duration
1001 a 2
1001 b 1
1001 a 2
1002 c 1
1002 c 1
我尝试了窗口函数和自连接,但似乎不起作用。非常感谢你的帮助
我的错误sql代码:
挑选*
从…起
选择*
由StartTime作为lead_EntityId通过videoId命令进行的LeadEntityId超额分配,
提前期通过videoId超额支付,以StartTime作为提前期
从
B
其中EntityId=lead\u EntityId
和结束时间+1=提前期\结束时间
我相信您可以做得更好,并优化这一组子查询,但目前我所做的是: 创建的表和插入的值:
create table myTable (VideoId int, StartTime int, EndTime int, EntityMid char);
insert into myTable values (1001, 1, 2, 'a');
insert into myTable values (1001, 2, 3, 'a');
insert into myTable values (1001, 3, 4, 'a');
insert into myTable values (1001, 7, 8, 'b');
insert into myTable values (1001, 10, 11,'a');
insert into myTable values (1001, 11, 12,'a');
insert into myTable values (1002, 4, 5, 'c');
insert into myTable values (1002, 7, 8, 'c');
以及查询:
select VideoId
, EntityMid
, Durationes
from
(
select VideoId
, EntityMid
, sum(Durationes) Durationes
, seq_nbr
from (
select VideoId
, EntityMid
, Durationes
, sum(new_grp) OVER ( PARTITION BY VideoId ORDER BY VideoId, StartTime) AS seq_nbr
from
(
select VideoId
, EntityMid
, (EndTime - StartTime ) as Durationes
, StartTime
, CASE
WHEN grouped = LAG (grouped) OVER ( PARTITION BY VideoId ORDER BY VideoId, StartTime, EntityMid)
THEN 0
ELSE 1
END AS new_grp
from
(
select VideoId
, EntityMid
, StartTime
, EndTime
, count('1')
, case
when ((LEAD(StartTime, 1) OVER (ORDER BY StartTime))-StartTime) = 1 and VideoId = (LEAD(VideoId, 1) OVER (ORDER BY VideoId)) then 1
when (StartTime - (LAG(StartTime, 1) OVER (ORDER BY StartTime))) = 1 and VideoId = (LAG(VideoId, 1) OVER (ORDER BY VideoId)) then 1
end grouped
from myTable
group by VideoId
, StartTime
, EndTime
, EntityMid
order by VideoId
, StartTime
,EndTime
, EntityMid
) a
) b
) c
group by VideoId
, EntityMid
, seq_nbr
) d;
小提琴:这是一种缺口和孤岛问题 对于特定的数据,可以使用“左联接”来确定孤岛是否开始。然后使用累积总和和聚合:
select t.videoid, t.EntityMid,
max(t.EndTime) - min(t.StartTime) as duration
from (select t.*,
sum(case when tprev.EntityMid is null then 1 else 0 end) over
(partition by t.videoid order by t.StartTime) as grp
from t left join
t tprev
on t.videoid = tprev.videoid and
t.EntityMid = tprev.EntityMid and
t.StartTime = tprev.EndTime
) t
group by t.videoid, t.EntityMid, grp;
是一个dbfiddle为什么末尾有两个EntityId为'c'的记录?我本以为那个岛会被报道为一个单一的记录。您可以包括您迄今为止尝试过的SQL吗?@TimBiegeleisen这两个c行没有StartTimen+1=EndTimen我们希望您到目前为止尝试了一些解决问题的方法,请向我们展示您的努力。@TimBiegeleisen因为Starttime和endtime不连续,所以它将分别报告两条记录。看起来您的错误代码中有一个额外的结束括号。在您的子选项中可能有多余的*,它不会返回OP要求的数据@VBokšić。谢谢你摆好小提琴。我把grp排除在小组之外了。它现在起作用了:。不客气:仍然没有得到与这里相同的结果:我想得到以下结果:。@VBokšIć。这次已修复并检查。@Gordon Linoff它对我有效。非常感谢你的聪明方法!