我有一个表,其中包含了一个车辆跟踪器产生的事件。这个表叫做tMain(因为它是我的主表),这里重要的列是cVehicleId,cFixedId(事件ID)和cDateTime。ID是整数,cDateTime是datetime2(7).cFixedId可以是NEWTRIP(67)、DEPART(63)、STOP(64)、PROCEED(65)和DELIVER(66)中的一个。这通常也是事件产生的顺序.该表包含了一个车队产生的事件。车辆中的跟踪器也提供了DateTime,所以该表一般是按DateTime排序的,但不一定100%(因为跟踪器可能不是100%同步)。每个车辆的事件不会是连续的(因为有许多车辆同时报告),但它们会按时间排序。
例如(针对1辆车)。
cId cDateTime cVehicleId cFixedId
62462946 2020-06-01 15:47:35.000 27 66
62462476 2020-06-01 15:37:58.000 27 65
62461602 2020-06-01 15:14:43.000 27 64
62461422 2020-06-01 15:11:08.000 27 63
62461407 2020-06-01 15:10:47.000 27 67
我想要的是一个查询,将所有的DELIVER事件和前面的DEPART(或者NEWTRIP)事件一起返回,看看这次旅行花了多长时间。这个查询应该是这样的:我试着找到所有的DEPART事件和前面的DEPART(或者NEWTRIP)事件,看看行程用了多长时间。
cVehicleId cFixedId cDateTime cFixedId cDateTime
27 67 2020-06-01 15:10:47.000 66 2020-06-01 15:47:35.000
我试过找到所有的DEPART事件 然后向前搜索下一个具有相同VehicleId的事件,其EventId为DELIVER. 或者找到所有DELIVER事件,然后往后搜索最近的具有相同VehicleId的DEPART事件。
我已经尝试了很多使用自连接的查询,也考虑过使用LEAD或LAG函数,但我认为这些对我没有帮助。我就是不能让它工作。
我目前有的是。
DECLARE @DEPART int = 63;
DECLARE @DELIVER int = 66;
DECLARE @StartDate DATE = '2020-05-01';
DECLARE @StopDate DATE = '2020-05-02';
select * from
(select cVehicleid, cDatetime, cFixedId from tMain where cFixedId = @DEPART and cDateTime > @StartDate and cDateTime < @StopDate) as t1
inner join
(select top(1) cVehicleId, cDatetime, cFixedId from tMain where cFixedId = @DELIVER and cDateTime > @StartDate and cDateTime < @StopDate order by cDateTime) as t2 on t2.cVehicleId = t1.cVehicleId and t2.cDateTime > t1.cDateTime
但是,这个结果是: 毫无.
我不知道自己做错了什么,也不知道该如何继续。也许还有更好的方法,但我不知道。我在网上搜了很多资料,但没有找到任何能让我找到解决办法的东西。谁能给我一个提示?
不太重要的额外问题:如果结果能按VehicledId分组就更好了,但这不是绝对的必须。
我想要的是一个查询,返回所有的DELIVER事件和前面的DEPART(或者NEWTRIP)事件,看看这个行程花了多长时间。
如果我理解正确的话,你可以使用 apply
:
select d.*, previous.*
from tmain d outer apply
(select top (1) e.*
from tmain e
where e.cVehicleId = d.cVehicleId and
e.cFixedId in ('DEPART', 'NEWTRIP') and
e.cDateTime < d.cDateTime
order by e.cDateTime desc
) previous
where d.ceventid = 'DELIVER';
为清晰起见,这里使用字符串版本。