2017-02-04 15 views
1

Пожалуйста, помогите!Статус автомобиля на 15-минутных интервалах aka status changes aka usage

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

любые указатели/решения были бы чрезвычайно оценены.

Я предполагаю, что запрос должен оглянуться назад и найти предыдущее изменение статуса, а затем заполнить каждые 15-минутный интервал этим, до следующего.

SELECT top 1000 
RM.RESOURCE_CALLSIGN 
,RM.MESSAGE_DATE 
,DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, MESSAGE_DATE)/15.0, 0) * 15, 0) [Interval] 
,[MESSAGE] 
,RM.STATUS_WAS 
,RM.STATUS_BECAME 
FROM [MOBILISATIONS].[dbo].[RESOURCE_MESSAGE] RM 
where RESOURCE_CALLSIGN like '_____' and MESSAGE like '%status change%' 

это кусок кода, который я нашел, чтобы сделать таблицу с каждым 15-минутного интервала с момента указанной даты:

declare @timetbl table(t datetime) 
declare @t datetime 
set @t = '2017-01-01 00:00:00' 
while @t <= getdate() 
begin 
insert into @timetbl values (@t) 
set @t = dateadd(mi, 15, @t) 
end 
select * from @timetbl 

ответ

0

Вы можете получить первую запись в каждом интервале, выполнив:

SELECT RM.* 
FROM (SELECT RM.*, 
      DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, MESSAGE_DATE)/15.0, 0) * 15, 0) as [Interval], 
      ROW_NUMBER() OVER (PARTITION BY DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, MESSAGE_DATE)/15.0, 0) * 15, 0) 
           ORDER BY MESSAGE_DATE) as seqnum 
     FROM [STATUSCHANGES].[dbo].[RESOURCE_MESSAGE] RM 
     WHERE RESOURCE_CALLSIGN like '_____' and MESSAGE like '%status change%' 
    ) RM 
WHERE seqnum = 1; 

Затем, вы можете получить предыдущее значение с помощью LAG():

SELECT RM.*, 
     (CASE WHEN LAG(MESSAGE_DATE) OVER (ORDER BY MESSAGE_DATE) < DATEADD(MINUTE, -15, MESSAGE_DATE) 
      THEN STATUS 
      ELSE LAG(STATUS) OVER (ORDER BY MESSAGE_DATE) 
     END) as prev_status 
FROM (SELECT RM.*, 
      DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, MESSAGE_DATE)/15.0, 0) * 15, 0) as [Interval], 
      ROW_NUMBER() OVER (PARTITION BY DATEADD(MINUTE, ROUND(DATEDIFF(MINUTE, 0, MESSAGE_DATE)/15.0, 0) * 15, 0) 
           ORDER BY MESSAGE_DATE) as seqnum 
     FROM [STATUSCHANGES].[dbo].[RESOURCE_MESSAGE] RM 
     WHERE RESOURCE_CALLSIGN like '_____' and MESSAGE like '%status change%' 
    ) RM 
WHERE seqnum = 1; 

Это не заполняет недостающие данные, но он получает предыдущий статус (который, судя по всему, является сутью вашего вопроса).

+0

Это замечательно, очень цените это. как вы переходите на следующий уровень и получаете 142 статусов грузовиков за интервал? то есть, если грузовик переходит в состояние 3 в 1 час, он должен оставаться статусом 3 на столько интервалов, сколько требуется, пока он не достигнет статуса 4. –

+0

@ApolloGerolymbos. , , Ваш вопрос кажется очень широким. Неясно, какая часть является реальной проблемой. Этот ответ касается того, что я считал основной проблемой. –

+0

Спасибо, что вернулся. Сочетание вашей более ранней справки и google, и я ее взломал. Теперь у меня есть статус каждого грузовика на 15-минутный интервал, даже если они не внесли изменений, то есть запрос оглядывается назад и находит предыдущее изменение. Если вы хотите, чтобы код, пожалуйста, дайте мне знать, но слишком длинный для этого комментария! –