2015-01-15 2 views
1

У меня есть таблица событий, каждая строка имеет Start Time и End Time, но я хочу подсчитать количество секунд, в течение которых событие активно за 10 минут.Преобразование даты на следующую 10-ю минуту

ТАБЛИЦА

StartTime    EndTime     AssetID EventID 
.........    ........    ....... ........ 
2014/12/01 10:29:50 2014/12/01 10:32:09  10  10045 
2014/12/01 10:29:55 2014/12/01 10:45:10  11  10046 
2014/12/01 10:33:12 2014/12/01 11:01:45  10  10047 

Желаемая Выход: -

 Time    DurationActiveSeconds  AssetID   EventID 
.................  ....................  .........  ....... 
2014/12/01 10:30:00  10       10   10045 
2014/12/01 10:30:00  5       11   10046 
2014/12/01 10:40:00  129      10   10045 
2014/12/01 10:40:00  408      10   10047 
2014/12/01 10:40:00  600      11   10046 
2014/12/01 10:50:00  600      10   10047 
2014/12/01 10:50:00  310      11   10046 
2014/12/01 11:00:00  600      10   10047 
2014/12/01 11:10:00  105      10   10047 

Я хотел бы закончить с Time Stamp 10 интервалов для каждого AssetID и EventID, где продолжительность работал в секундах за период, когда событие активно, я запускаю это в течение месяца, если событие началось в pr в течение месяца, отсчет будет начинаться с полуночи 1-го.

Я уже построил таблицу календаря с записью на каждую секунду, но не могу определить, как группировать данные по мере необходимости.

Edited Подробности
Если взять первую строку данных, актив 10 перестал работать в 10:29:50 и снова начал работать в 10:32:09, что я хочу видеть, как мой набор результатов два временных интервала с десятиминутными интервалами: -
10:30 и 10:40 с 10 секундами, вычитаемыми с 600 (количество секунд в 10 минут) в течение 10:30 и 129 секунд, вычитаемых из 600 за период 10:40 , обеспечивая таблицу, как показано ниже: -

EndPeriod  Asset Event Duration 
    ...........  ..... ..... ........ 
2014/12/01 10:30:00 10 10045 590 
2014/12/01 10:40:00 10 10045 471 

Вот несколько больше исходных данных: -
время_запуска, EndTime, активов, EventID, Продолжительность
2014-10-01 10: 29: 50,000, 2014-10- 01 10: 32: 09 000, Asset01, 710, 138.9999998
2014-10-01 15: 26: 43.000, 2014-10-01 15: 27: 30.000, Asset02, 10, 46.99999967
2014-10-01 15: 26: 44 000, 2014-10-01 15: 36: 44 000, Asset02, 5760, 599.9999994
2014-10-01 16: 33: 48.000, 2014-10-01 16: 43: 49.000, Asset01, 5760, 601.0000003
2014 -10-01 16: 33: 48 000, 2014-10-01 16: 34: 35 000, Asset01, 10, 47.0000003
2014-10-01 16: 47: 48.000, 2014-10-01 16: 48: 35 000, Asset02, 10, 46.99999967
2014-10-01 20: 55: 20.000, 2014-10-01 20: 56: 07.000, Asset02, 10, 47.0000003
2014-10-01 21: 47: 45.000, 2014-10 -01 21: 48: 33 000, Asset02, 10, 47.99999991
2014-10-01 23: 04: 12.000, 2014-10-01 23: 05: 00.000, Asset02, 10, 47.99999991
2014-10-02 03 : 35: 36 000, 2014-10-02 03: 36: 23 000, Asset02, 10, 46.99999967
2014-10-02 04: 56: 22.000, 2014-10-02 04: 57: 09.000, Asset01, 10, 46.99999967
2014-10-02 04: 57: 08.000, 2014-10-02 05: 11: 49.000, Asse t01, 6200, 880.9999997
2014-10-02 05: 14: 06.000, 2014-10-02 05: 29: 52.000, Asset02, 6200, 945.9999999
2014-10-02 05: 24: 40.000, 2014-10 -02 05: 25: 27 000, Asset01, 10, 47.0000003
2014-10-02 06: 15: 06.000, 2014-10-02 06: 15: 53.000, Asset02, 10, 47.0000003
2014-10-02 07 : 01: 00 000, 2014-10-02 07: 01: 48 000, Asset02, 10, 47.99999991
2014-10-02 11: 34: 58.000, 2014-10-02 11: 35: 45.000, Asset02, 10, 46 ,99999967
2014-10-02 11: 42: 02.000, 2014-10-02 11: 44: 21.000, Asset01, 65, 138.9999998
2014-10-02 14: 43: 35.000, 2014-10-02 14: 44: 22 000, Asset01, 10, 47.0000003
2014-10-02 14: 51: 12.000, 2014-10-02 14: 51: 59.000, Asset02, 10, 47.0000003
2014-10-03 12: 00: 00.000 , 2014-10-03 12: 00: 47 000, Asset02, 10, 47.0000003
2014-10-04 11: 29: 03.000, 2014-10-04 11: 32: 00.000, Asset01, 68, 176.9999999
2014- 10-05 04: 51: 19 000, 2014-10-06 21: 15: 33 000, Asset02, 5000, 145454
2014-10-05 08: 19: 44.000, 2014-10-05 08: 20: 32.000, Asset02 , 10, 48.00000053
2014-10-05 08: 26: 34,000, 2014-10-05 08: 27: 21,000, Asset01, 10, 46,99999967

Я надеюсь, что это имеет смысл

Большое спасибо, что нашли время, чтобы прочитать эту
Марк

+0

группировать по столбцам, которые вы не агрегирования: Время, AssetID, EventID. Также вы отметили как MySQL, так и SQL Server. Это не может быть и то, и другое? –

+0

Его MSSQL 2012, а не MySQL, извиняется за опечатку, можете ли вы предоставить мне пример группы, пожалуйста, так как я не уверен, как получить ее для группировки с интервалом в 10 минут? Many Thanks – Sh0t2bts

ответ

0

я думаю, что вы ищете что-то вроде

SUM (StartTime BETWEEN [calculated first time] AND [calculated last time]). 

это поможет вам? Или я неправильно понял ваш вопрос?

+0

Я борюсь с расщеплением времени на разные 10-минутные периоды и подсчитывая количество секунд в каждом периоде. – Sh0t2bts

0

ОБРАЗЦА ТАБЛИЦА

CREATE TABLE #TEMP(StartTime DATETIME,EndTime DATETIME,AssetID INT,EventID INT) 

INSERT INTO #TEMP    

SELECT '2014/12/01 10:29:50', '2014/12/01 10:32:09',  10 ,  10045 
UNION ALL 
SELECT '2014/12/01 10:29:55', '2014/12/01 10:45:10',  11,  10046 
UNION ALL 
SELECT '2014/12/01 10:33:12', '2014/12/01 11:01:45',  10,  10047 

QUERY

Используйте recursive CTE, чтобы получить даты между ними. Внутри CTE, Я преобразовал минуту к следующей 10-й минуте во фракции 10, т.е. мин-32 превращают в минуту-40, минута-29 преобразуется в минуту-30 и т.д.

;WITH CTE AS 
( 
    SELECT StartTime,EndTime,AssetID,EventID, 
     -- Select the first word from Hour, cast to varchar, append with 0 to get next 10th minute 
     MIN(DATEADD(MINUTE,10,CAST(CAST(CAST(StartTime AS DATE)AS VARCHAR(12)) + ' ' + 
     CAST(DATEPART(HOUR,StartTime)AS VARCHAR(2)) + ':' + 
     CAST(LEFT(RIGHT('0'+LEFT(DATEPART(MINUTE,StartTime),2),2),1) AS VARCHAR(2))+ '0' +':00' AS DATETIME)))NewStartTime,  
     MIN(DATEADD(MINUTE,10,CAST(CAST(CAST(EndTime AS DATE)AS VARCHAR(12)) + ' ' + 
     CAST(DATEPART(HOUR,EndTime)AS VARCHAR(2)) + ':' + 
     CAST(LEFT(RIGHT('0'+LEFT(DATEPART(MINUTE,EndTime),2),2),1) AS VARCHAR(2))+ '0' +':00' AS DATETIME)))NewEndTime   
     FROM #TEMP 
     GROUP BY StartTime,EndTime,AssetID,EventID 
) 
,CTE2 AS 
(
    -- Find the difference in secnods with the 10th minute and orginal time 
    SELECT *, 
    DATEDIFF(S,StartTime,NewStartTime) StartDiff, 
    DATEDIFF(S,DATEADD(MINUTE,-10,NewEndTime),EndTime)EndDiff 
    FROM CTE 
) 
,CTE3 AS 
(
    -- Recursive CTE(loop) to find in-between dates 
    SELECT MIN(NewStartTime)StartTime,AssetID,EventID 
    FROM CTE2 
    GROUP BY AssetID,EventID 
    UNION ALL 
    SELECT DATEADD(MINUTE,10,C.StartTime),C.AssetID,C.EventID  
    FROM CTE3 C 
    JOIN CTE2 T ON C.AssetID=T.AssetID AND C.EventID =T.EventID 
    WHERE C.StartTime < NewEndTime 
) 
SELECT DISTINCT C3.*, 
CASE 
    WHEN C3.StartTime=C2.NewStartTime THEN C2.StartDiff 
    WHEN C3.StartTime=C2.NewEndTime THEN C2.EndDiff 
    ELSE 600 
END AS ACT 
FROM CTE3 C3 
LEFT JOIN CTE2 C2 ON (C3.StartTime=C2.NewStartTime OR C3.StartTime=C2.NewEndTime) 
AND C2.AssetID=C2.AssetID AND C3.EventID =C2.EventID 
OPTION(MAXRECURSION 0) 
  • Click here для просмотра результат
+0

Привет, Спасибо за запрос. Округление минут до следующего 10-минутного блока - это именно то, что мне нужно, я раньше не использовал CTE, с указанным выше запросом я не получил продолжительность, в которой событие было активным в данных 10 минутный период, можете ли вы помочь и посоветовать, как я хотел бы добавить это, пожалуйста?Many Thanks – Sh0t2bts

+0

Все отработанные и работающие сейчас, код, который вы предоставили, работал отлично, мне нужно было только добавить DateDiff (ss, StartTime, EndTime) в запрос для решения моих проблем. ваш лучший Гуру SQL Спасибо. – Sh0t2bts

+0

Спасибо. К сожалению !!! Я забыл дать вам DateDiff. Скоро будет обновление @ Sh0t2bts –

0

Если вы просто хотите, чтобы округлить datetime до следующего 10-минутного интервала, то формула вы можете использовать это:

DATEADD(minute,((DATEDIFF(minute,0,<Value to Round>)/10+1)*10),0) 

E.g. на текущий момент:

DATEADD(minute,((DATEDIFF(minute,0,CURRENT_TIMESTAMP)/10+1)*10),0) 

Только что вернулся для меня:

2015-01-16 08:00:00.000