我有一个GPS应用程序,可以将数据保存到下表:
CREATE TABLE [dbo].[T_Tracking]
(
[id] [int] IDENTITY(1,1) NOT NULL,
[IMEI] [nvarchar](50) NULL,
[TrackTime] [datetime] NULL,
[Longitude] [nvarchar](50) NULL,
[Lattitude] [nvarchar](50) NULL,
[speed] [float] NULL,
[CarID] [int] NULL,
[Country] [nvarchar](50) NULL,
[City] [nvarchar](50) NULL,
[Area] [nvarchar](50) NULL,
[Street] [nvarchar](50) NULL,
[FullAddress] [nvarchar](150) NULL,
[Distance] [float] NULL
-- ...
)
我想做一个旅行查询拉回开始时间&速度,结束时间和速度。
这是我的疑问:
SELECT id
, IMEI
, TrackTime as StartTime
, speed as StartSpeed
, CarID
, FullAddress
, (
SELECT TOP (1) TrackTime AS Expr1
FROM T_Tracking AS E2
WHERE (CarID = E1.CarID)
AND (id > E1.id)
AND (speed <5)
ORDER BY id desc
) AS StopTime
, (
SELECT TOP (1) speed AS Expr1
FROM T_Tracking AS E2
WHERE (CarID = E1.CarID)
AND (id > E1.id)
AND (speed <5)
ORDER BY id desc
) AS EndSpeed
FROM T_Tracking AS E1
WHERE (speed > 5)
order by id desc
它工作正常,但是如果这次旅行应该停车15分钟(即因为汽车可能停在交通中一分钟或者2分钟,那么我们不希望计算作为旅行的结束) 我该如何添加这个逻辑?
此外,我需要将距离场相加以获得行程总距离。
样本表数据:
期望的结果是:
注意:
speed=0
它将是speed<5
(设备准确度/容差)答案 0 :(得分:0)
这是演示如何获得停止的演示。为简单起见,我使用所有INT来表示时间和速度,查询可以很容易地适应DATETIME数据类型。如果持续时间> 1,则记录停止。 4。
SELECT CarID, stopped, grp
, min(TrackTime) stopStartTime
, max(TrackTime) + 1 - min(TrackTime) stopDuration
FROM (
SELECT id, TrackTime, CarID, stopped
, row_number() over (partition by CarID order by TrackTime) - row_number() over (partition by CarID, stopped order by TrackTime) grp
FROM (
SELECT id, TrackTime, CarID, CASE WHEN speed > 5 THEN 0 ELSE 1 END stopped
FROM (
-- Demo data
VALUES
(0,0,10, 2)
,(1,1,10, 8)
,(2,2,10, 8)
,(3,3,10, 4)
,(4,4,10, 4)
,(5,5,10, 4)
,(6,6,10, 4)
,(7,7,10, 4)
,(8,8,10, 4)
,(9,9,10, 8)
) T_Tracking (id, TrackTime, CarID, speed)
) g
) t
GROUP BY CarID, stopped, grp
HAVING max(TrackTime) + 1 - min(TrackTime) > 4
ORDER BY min(TrackTime)
答案 1 :(得分:0)
试试这个(未经测试):
select JourneyBounds.id
, JourneyBounds.IMEI
, JourneyBounds.TrackTime as StartTime
, JourneyBounds.speed as StartSpeed
, JourneyBounds.CarID
, JourneyBounds.FullAddress
, max(journey.TrackTime) StopTime
, max(case when journey.id = JourneyBounds.EndOfJourneyId then journey.speed else null end) EndSpeed
, JourneyBounds.Distance + sum(journey.Distance) TotalDistance
from (
select *
, (
select min(id)
from T_Tracking EndOfJourney
where EndOfJourney.Id > StartOfJourney.Id
and EndOfJourney.CarId = StartOfJourney.CarId
and EndOfJourney.speed < 5
--edit; car must have been stopped for 15 mins; so we need to check that the records after this stop confirm that (i.e. that the car does not move in that time)
and not exists (
select top 1 1
from T_Tracking WaitFifteenMins
where WaitFifteenMins.Id > EndOfJourney.Id
and WaitFifteenMins.TrackTime <= DateAdd(minute, 15, EndOfJourney.TrackTime)
and WaitFifteenMins.speed >= 5
)
--end of edit
) EndOfJourneyId
from T_Tracking StartOfJourney
where StartOfJourney.speed < 5
) JourneyBounds
inner join T_Tracking journey
on journey.CarId = JourneyBounds.CarId
and journey.id > JourneyBounds.Id
and journey.id <= JourneyBounds.EndOfJourneyId
group by JourneyBounds.id
, JourneyBounds.IMEI
, JourneyBounds.TrackTime
, JourneyBounds.speed
, JourneyBounds.CarID
, JourneyBounds.FullAddress
, JourneyBounds.Distance
having count(1) > 1
JourneyBounds
子查询获取speed < 5
的所有记录(即任何潜在旅程的起始记录)。此外,它会在该开始后拉回第一站的id
(即第一个具有更大id且速度小于5的记录)。
然后它会在内部联接中拉回在开始时间之后到达同一辆车的所有记录,直到&amp;包括此旅程的最终记录。然后,我们通过将这段旅程中记录的所有距离相加来计算距离。
最后的having count(1) > 1
只是说如果汽车的开始记录后立即停止,我们可以假设它没有移动/没有旅程。据推测,我们不希望在结果中出现这些非旅程。