2013-12-16 3 views
-1

В настоящее время я работаю над написанием запроса на сервере Microsoft SQL. Таблица, в которой я получаю данные, выглядит следующим образом:Сравнение дат в отдельных строках SQL

From_State || To_State || Event_Date 
------------------------------------ 
4   || 8  || 2013-12-10 14:15:55.320 
8   || 1  || 2013-12-10 14:29:36.823 
1   || 4  || 2013-12-10 14:30:10.230 
4   || 8  || 2013-12-10 15:56:08.077 
8   || 1  || 2013-12-10 21:03:44.053 
1   || 4  || 2013-12-10 21:04:17.470 

4 = testing, 1 = idle and 8 = offline.

Мне нужно получить процентное соотношение дня, которое испытывалось оборудованием, сравнивая эти отметки времени. Я бы хотел, чтобы на этот день запрос подсчитал, что оборудование тестировалось в течение 76% дня.

Также будет некоторое время в начале дня, возможно, что будет труднее подобрать, поскольку он перекрывается с предыдущим днем ​​и тем же в конце. Любая помощь будет оценена!

+1

Не могли бы вы добавить, какой результат вы ожидаете от данных образца, которые вы предоставили? – gotqn

+0

Я думаю, что OP нуждается в сумме дат, когда состояния меняются от 4 до любого! 4 – jean

+0

В конце концов мне просто нужно процент от того дня, когда оборудование находилось в состоянии 4, будет предоставлен диапазон дат, но если я смогу выяснить как это сделать в течение одного дня, это будет легко реализовать для диапазона дат. – user3108375

ответ

0

Фигурные его, вот мое решение для этого:

DECLARE 
     @equipment_id INT = 295, 
     @start_date DATE = '12/01/2013', 
     @end_date DATE = '12/11/2013'; 

-- Get initial data 
WITH data AS 
( 
     -- Ensure rownumber exists to simplify operations 
     SELECT ROW_NUMBER() OVER(ORDER BY event_date) AS rownum, 
      from_state_id, 
      to_state_id, 
      event_date 
     FROM [triggers].[equipment_state_change] 
     WHERE equipment_id = @equipment_id 
     AND CAST(event_date AS DATE) >= @start_date AND CAST(event_date AS DATE) <= @end_date 
), 
-- Determine time differences 
data_with_time_differences AS 
(
     SELECT 
      thisRecord.rownum, 
      thisRecord.to_state_id, 
      thisRecord.event_date, 
      CASE WHEN lastRecord.rownum IS NULL OR CAST(lastRecord.event_date AS DATE) < CAST(thisRecord.event_date AS DATE) THEN 
        DATEDIFF(mi, CAST(thisRecord.event_date AS DATE), thisRecord.event_date) 
       WHEN CAST(thisRecord.event_date AS DATE) < CAST(nextRecord.event_date AS DATE) THEN 
        DATEDIFF(mi, thisRecord.event_date, CAST(nextRecord.event_date AS DATE)) 
      ELSE 
        DATEDIFF(mi, lastRecord.event_date, thisRecord.event_date) 
      END AS minutes_in_state, 
      -- Mark Records that will be used for % calculation as 4 
      CASE WHEN CAST(thisRecord.event_date AS DATE) < CAST(nextRecord.event_date AS DATE) AND thisRecord.to_state_id = 4 THEN 
        4 
       ELSE 
        thisRecord.from_state_id 
      END AS recordToCalculateFrom 
     FROM data thisRecord 
     LEFT JOIN data lastRecord ON lastRecord.rownum = thisRecord.rownum - 1 
     LEFT JOIN data nextRecord ON nextRecord.rownum = thisRecord.rownum + 1 
) 

SELECT SUM(CAST(minutes_in_state AS FLOAT)) /60 /24 * 100 as PercentageOfDayTesting, CAST(event_date AS DATE) as Date 
from data_with_time_differences 
where recordToCalculateFrom = 4 
group by CAST(event_date AS DATE) 
order by Date 

Это получение моих ожидаемых результатов. Может быть, это поможет кому-то там. Если неясно, что я здесь делаю, не стесняйтесь спрашивать.

Смежные вопросы