2012-03-06 93 views
1

我有一張表格,其中包含來自GPS模塊的位置和時間戳記信息。該表看起來是這樣的:SQL Server 2008:循環播放SELECT +根據循環中的位置執行其他查詢的結果和結果

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) 

你會發現,一些數據點的有0緯度和經度值,由於GPS模塊沒有在當時的修復程序。從該表中檢索數據點時,我想要執行的操作是將所有零緯度和經度值設置爲最後一次非零緯度和經度值。我目前在我的客戶端代碼中執行此操作,但我想將其集成到我的數據庫存儲過程中。客戶端代碼看起來是這樣的:

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中有相同的功能?

附錄:感謝迄今爲止的所有迴應。我應該指出,我不想更新原始表 - 我只想修改查詢的結果。原因是因爲表中的行不按時間順序添加。

+0

關於您的附錄,danihp的回答正是您所需要的。 – aaroncatlin 2012-03-06 12:17:20

+0

你爲什麼不忽略它們?即從@VehicleData中選擇*,其中<> 0和經度<> 0 – Adrian 2012-03-06 12:17:42

+0

@Adrian:爲了簡化我的問題,我沒有包含完整的表格描述。除了時間和地點,每行還有一些與當時模塊狀態有關的數據。即使沒有有效的位置,我也需要這些信息。 – 2012-03-06 12:26:39

回答

2

您可以子查詢表來獲得最後knowed位置:

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 

樣品是緯度,做同樣的子查詢得到經度。

+0

這正是我需要的,謝謝。我有一個關於性能的問題:在我的示例客戶端代碼中,我只是在開始時查詢數據庫中最後一個非零位置。之後,我存儲該位置的本地副本並在需要時使用它。在您的查詢中,每當經度或緯度爲零時,就會執行一條select語句。我很好奇這將如何影響性能。 – 2012-03-06 12:23:19

+0

要提高性能,請記住在TimeStamp列上創建索引。 – danihp 2012-03-06 12:33:07

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

您可以將這兩個UPDATE合併到一個單獨的UPDATE中,像'SET Latitude =(...),Longitude =(...)FROM [...] WHERE Latitude = 0和Longitude = 0'。這也將保護緯度= 0和經度<> 0的任何條目(反之亦然)。 OP沒有說過這是否是一種有效的可能性:-) – 2012-03-06 11:59:52

+0

這是真的,克里斯。 – aaroncatlin 2012-03-06 12:14:52

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