我正在寻找一个sql查询,它将以下表数据作为输入
ID Start date end date
ID1 01.01.2016 31.12.2016
ID2 01.02.2016 30.06.2016
ID3 01.10.2016 31.10.2016
ID4 01.02.2016 31.07.2016
并提供以下输出
ID1 01.01.2016 31.01.2016
ID4 01.02.2016 31.07.2016
ID1 01.08.2016 30.09.2016
ID3 01.10.2016 31.10.2016
ID1 01.11.2016 31.12.2016
请注意,由于ID2,ID3和ID4与ID1重叠,因此ID1仅拆分一个月。 这个想法是最新的日期范围获得偏好。如果你看到输出ID2完全被拒绝,因为它被ID4覆盖。
请您发布查询提示。
答案 0 :(得分:0)
我已经想到了这样做的一些逻辑。我可以给出sql server的语法(但你必须找到mysql的语法)。将[表名]替换为后续查询中表的名称。
从表中获取最大结束日期并存储在变量中:
declare @max_end_date datetime
set @max_end_date = (select max([end date]) from [Table Name])
将可能的开始日期收集到临时表中,添加行号和两个空白列(''作为id,0作为dupe):
select
row_number()over(order by start_date) as row,
start_date,
'' as id,
0 as dupe
into #temp
from
(select [start date] as start_date
from [Table Name]
union
select dateadd(day,1,[end date])
from [Table Name]
where [end date] <> @max_end_date )
group by start_date
更新临时表的每一行,并在该开始日期生效:
update #temp
set #temp.id = c.id
from #temp
left outer join
(select a.start_date, max(b.id) as id
from #temp a
inner join [Table Name] b
on a.start_date between b.[start date] and b.[end date]
group by a.start_date) c
on #temp.start_date = c.start_date
使用标志更新临时表以标记“重复”行:
update #temp
set #temp.dupe = 1
from #temp
inner join #temp b
on a.row = b.row + 1
and a.id = b.id
删除重复的行:
delete from #temp where dupe = 1
更新行列:
update #temp
set row = row_number()over(order by start_date)
将此表连接到自身以创建您所追求的表:
select
a.id as id,
a.start_date as start_date,
isnull(dateadd(day,-1,b.start_date),@max_end_date) as end_date
from #temp a
left outer join #temp b
on a.row = b.row - 1