问题是它在SQL中需要很长时间并且必须有更好的方法。我已经选择了下面的场景的缓慢部分。 场景: 两个(临时)表,其中包含必须配对的车辆的开始和结束事件时间,以计算空闲持续时间。问题是缺少一些事件数据。我想出了一个基本的方法,确定最后结束时间是在下一个开始时间之后,并删除无效的开始。再次不优雅+非常慢。
表格:
create table #start(VehicleIp int null, CurrentDate datetime null,
EventId int null,
StartId int null)
create table #end(VehicleIp int null,
CurrentDate datetime null,
EventId int null,
EndId int null)
- //注意:StartId和EndId都预先填充了类似的内容:
ROW_NUMBER() Over(Partition by VehicleIp order by VehicleIp, CurrentDate)
- //慢速SQL
while exists(
select top 1 tOn.EventId
from #start as tOn
left JOIN #end tOff
on tOn.VehicleIp = tOff.VehicleIp and
tOn.StartID = tOff.EndID +1
)
begin
declare @badEntry int
select top 1 @badEntry = tOn.EventId
from #s as tOn
left JOIN #se tOff
on tOn.VehicleIp = tOff.VehicleIp and
tOn.StartID = tOff.EndID +1
order by tOn.CurrentDate
delete from #s where EventId = @badEntry
;with _s as ( select VehicleIp, CurrentDate, EventId,
ROW_NUMBER() Over(Partition by VehicleIp
order by VehicleIp, CurrentDate) StartID
from #start)
update #start
set StartId = _s.StartId
from #s join _s on #s.EventId = _s.EventId
end
答案 0 :(得分:1)
假设您从包含Vehicle和使用它的间隔的表开始,此查询将识别间隙。
select b.VehicleID, b.IdleStart, b.IdleEnd
from
(
select VehicleID,
-- If EndDate is not inclusive, remove +1
EndDate + 1 IdleStart,
-- First date after current for this vehicle
-- If you don't want to show unused vehicles to current date remove isnull part
isnull((select top 1 StartDate
from TableA a
where a.VehicleID = b.VehicleID
and a.StartDate > b.StartDate
order by StartDate
), getdate()) IdleEnd
from TableA b
) b
where b.IdleStart < b.IdleEnd
如果日期有时间部分,则应将其截断为所需的精度,此处为日期:
dateadd(dd, datediff(dd,0, getDate()), 0)
用hh,mm或任何需要的精度替换dd。