SQL Server 2008: цикл по результатам SELECT + выполнения других запросов в зависимости от положения в цикле и результата - PullRequest
1 голос
/ 06 марта 2012

У меня есть таблица, в которой хранится информация о местонахождении и метке времени из модуля 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)

Вы заметите, что некоторые точки данных имеют значения широты и долготы, равные 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?

Добавление: Спасибо за все ответы до сих пор.Я должен отметить, что я не заинтересован в обновлении исходной таблицы - я хотел бы только изменить результаты запроса.Причина этого в том, что строки в таблице не добавляются в хронологическом порядке.

Ответы [ 3 ]

2 голосов
/ 06 марта 2012

Вы можете использовать таблицу подзапросов для получения последней известной позиции:

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 голосов
/ 06 марта 2012

Может быть немного грязно, но добавление этих двух команд в ваш 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
0 голосов
/ 06 марта 2012
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...