SQL Server 2008:根据循环和结果中的位置循环SELECT +执行其他查询的结果

时间:2012-03-06 11:33:09

标签: sql sql-server-2008

我有一张表格,其中包含GPS模块的位置和时间戳信息。该表看起来像这样:

declare @VehicleData table
(
    [TimeStamp] DateTime,
    Latitude float,
    Longitude float
)

insert into @VehicleData
values  ('2012/03/06 10:00', 1, 1),
        ('2012/03/06 10:01', 1, 2),
        ('2012/03/06 11:00', 0, 0),
        ('2012/03/06 11:01', 0, 0),
        ('2012/03/06 11:02', 2, 2),
        ('2012/03/06 11:03', 2, 2),
        ('2012/03/06 11:04', 2, 3),
        ('2012/03/06 11:20', 0, 0),
        ('2012/03/06 11:21', 5, 5),
        ('2012/03/06 11:22', 5, 6),
        ('2012/03/06 11:23', 5, 6),
        ('2012/03/06 11:24', 5, 7),
        ('2012/03/06 11:25', 5, 8)

您会注意到,由于GPS模块当时没有修复,因此某些数据点的纬度和经度值为0。从此表中检索数据点时,我想要做的是将所有零纬度和经度值设置为最后的非零纬度和经度值。我目前在客户端代码中执行此操作,但我想将其集成到我的数据库存储过程中。客户端代码看起来像这样:

Dim StartDate = '2012/03/06 11:00'
Dim EndDate = '2012/03/06 11:25'

Dim Results = GetVehicleDataBetweenDates(StartDate, EndDate)

Dim LastKnownLatitude = 0, LastKnownLongitude = 0

If Results(0).Latitude = 0 Then
    'Query database for last non-zero position before StartDate
    GetLastKnownPositionBeforeDate(StartDate, LastKnownLatitude , LastKnownLongitude )
Else
    LastKnownLatitude = Results(0).Latitude
    LastKnownLongitude = Results(0).Longitude
EndIf

For i = 0 to Results.Count - 1
    If Results(i).Latitude = 0 Then
        Results(i).Latitude = LastKnownLatitude
        Results(i).Longitude = LastKnownLongitude
    Else
        LastKnownLatitude = Results(i).Latitude
        LastKnownLongitude = Results(i).Longitude
    EndIf
Next

以上结果可能会产生以下结果,箭头指向前面的零位置:

('2012/03/06 11:00', 1, 2), <-- 
('2012/03/06 11:01', 1, 2), <--
('2012/03/06 11:02', 2, 2),
('2012/03/06 11:03', 2, 2),
('2012/03/06 11:04', 2, 3),
('2012/03/06 11:20', 2, 3), <--
('2012/03/06 11:21', 5, 5),
('2012/03/06 11:22', 5, 6),
('2012/03/06 11:23', 5, 6),
('2012/03/06 11:24', 5, 7),
('2012/03/06 11:25', 5, 8)

我如何在SQL中实现相同的功能?

附录:感谢目前为止的所有回复。我应该指出我对更新原始表不感兴趣 - 我只想修改查询的结果。原因是因为表中的行没有按时间顺序添加。

3 个答案:

答案 0 :(得分:2)

可能有点乱,但将这两个命令添加到SQL中将按需要执行:

UPDATE V
SET Latitude = (SELECT Latitude FROM @VehicleData WHERE [TimeStamp] = (SELECT MAX([TimeStamp]) FROM @VehicleData WHERE [TimeStamp] < V.[TimeStamp] AND [Latitude] <> 0))
FROM @VehicleData V
WHERE Latitude = 0

UPDATE V
SET Longitude = (SELECT Longitude FROM @VehicleData WHERE [TimeStamp] = (SELECT MAX([TimeStamp]) FROM @VehicleData WHERE [TimeStamp] < V.[TimeStamp] AND [Longitude] <> 0))
FROM @VehicleData V
WHERE Longitude = 0

希望这有帮助。

这是我的结果集:

2012-03-06 10:00 | 1 | 1
2012-03-06 10:01 | 1 | 2
2012-03-06 11:00 | 1 | 2
2012-03-06 11:01 | 1 | 2
2012-03-06 11:02 | 2 | 2
2012-03-06 11:03 | 2 | 2
2012-03-06 11:04 | 2 | 3
2012-03-06 11:20 | 2 | 3
2012-03-06 11:21 | 5 | 5
2012-03-06 11:22 | 5 | 6
2012-03-06 11:23 | 5 | 6
2012-03-06 11:24 | 5 | 7
2012-03-06 11:25 | 5 | 8

答案 1 :(得分:2)

您可以使用子查询表来获取最后知道的位置:

select 
 [timestamp],
 case 
   when latitude>0 then latitude
   else (select top 1 latitude 
         from @VehicleData v2
         where 
           latitude > 0 and
           v2.[TimeStamp] < v1.[TimeStamp]
         order by v2.[TimeStamp] desc )
   end
   as latitude
from 
 @VehicleData v1

样本用于纬度,执行相同的子查询以获得经度。

答案 2 :(得分:0)

update  V
set latitude= (select top 1 latitude from VehicleData V2 where v2.timestamp < v.timestamp  and latitude!= 0 order by v2.timestamp desc),
    longitude= (select top 1 longitude from VehicleData V2 where v2.timestamp < v.timestamp and longitude !=0 order by v2.timestamp desc)
from VehicleData V
where V.latitude=0 and V.longitude=0