sql server—sql自联接表以查找与条件匹配的下一行

gwbalxhn  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(309)

我有一个包含由车辆追踪器生成的事件的表。这个表称为tmain(因为它是我的主表),这里的重要列是cvehicleid、cfixedid(事件id)和cdatetime。id是整数,cdatetime是datetime2(7)。cfixedid可以是newtrip(67)、depart(63)、stop(64)、procedue(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)事件,以查看旅行花费了多长时间。应该是这样的:

cVehicleId  cFixedId  cDateTime                cFixedId  cDateTime
27          67        2020-06-01 15:10:47.000  66        2020-06-01 15:47:35.000

我尝试的是查找所有离开事件,然后向前搜索具有eventid deliver的相同vehicleid的下一个事件。或者查找所有deliver事件,并向后搜索具有相同vehicleid的最近的Deve事件。
我已经尝试了很多使用自连接的查询,也考虑过使用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分组,那就好了,但这不是绝对必须的。

wixjitnu

wixjitnu1#

我想要的是一个查询,它返回所有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';

为了清晰起见,这将使用字符串版本。

相关问题