2016-05-23 4 views
3

У меня есть таблица вроде этого:граф секунд на переключатель интервал SQL Server

Value TimeStamp 
1 2016-04-01 00:01:09.000 
0 2016-04-01 00:01:09.000 
0 2016-04-01 00:01:37.000 
1 2016-04-01 00:01:37.000 
1 2016-04-01 00:04:52.000 
1 2016-04-01 00:09:58.000 
1 2016-04-01 00:15:05.000 
1 2016-04-01 00:20:11.000 
1 2016-04-01 00:24:49.000 
1 2016-04-01 00:29:55.000 
1 2016-04-01 00:31:19.000 
0 2016-04-01 00:31:19.000 
0 2016-04-01 00:31:46.000 
1 2016-04-01 00:31:46.000 
1 2016-04-01 00:35:01.000 
1 2016-04-01 00:40:07.000 
1 2016-04-01 00:44:46.000 
1 2016-04-01 00:49:52.000 
1 2016-04-01 00:54:58.000 
1 2016-04-01 01:00:04.000 
1 2016-04-01 01:01:28.000 
0 2016-04-01 01:01:28.000 
0 2016-04-01 01:05:10.000 
0 2016-04-01 01:09:49.000 

И я хочу, чтобы отсчитывать секунды, где значение 1 (переключатель ON) в день, вот сделка; Когда TIMESTAMP повторяет это означает, что произошло изменение от 0 до 1 или наоборот в значении переключателя, у меня уже было много aproches как:

Q1 AS (SELECT ROW_NUMBER() OVER (ORDER BY TimeStamp) AS id, 
Value, Timestamp 
FROM Q2 
GROUP BY idVBox, sensorType, sensorSubtype, timeStamp 
HAVING COUNT(TimeStamp) > 1) 

Then: 

SELECT A.Value, DATEDIFF(SECOND,A.TimeStamp,B.TimeStamp) 
FROM Q1 AS A 
INNER JOIN Q1 AS B 
ON B.ID = A.ID + 1 
AND B.ID%2 = 0 

Тогда группа по и Сумма, но здесь проблема в том, что я дон 't знать, если значение приходит в 1 или 0 из прошлого дня, и коммутатор может быстро изменить его состояние и никогда не получить фактическое значение его фактического состояния. Любая другая идея?

+0

Вы считаете секунды между включенными и выключенными? Как его можно включить и снова включить? Я что-то упускаю. Вы должны записывать несколько переключателей. Сколько всего коммутаторов? –

+0

Да, я хочу подсчитать время между Вкл и Выкл, где в середине последовательности находятся только строки с включенным переключателем (значение = 1). Имеется только ona-переключатель, когда времяStamps повторяется, когда коммутатор переключается. – Jorge

ответ

1

Если вы используете SQL Server 2012, вы можете эффективно использовать функцию LAG(). Сначала присоедините таблицу к повторяющимся датам, где значение = 1. Затем вычислите разницу между включенными и предыдущими. Наконец, подведите итог.

ПРИМЕЧАНИЕ. LAG() возвращает null для первого дня.

SELECT 
    Seconds=SUM(X.Seconds) 
FROM 
(
    SELECT 
     Seconds=DATEDIFF(SECOND,LAG(T1.TimeStamp) OVER (ORDER BY T1.TimeStamp),T1.TimeStamp)  
    FROM 
     MyTable T1 
     INNER JOIN MyTable T2 ON T2.TimeStamp=T1.TimeStamp AND T1.Value<>T2.Value 
    WHERE 
     T1.Value=1 
)AS X 
+0

Код, как есть, добавляет время, когда значение 0 – Alex

+0

Я хотел сказать, что он подсчитывает секунды для обоих 0s и 1s – Alex

+0

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

2

Что вы хотите сделать, добавляет переключатель состояния фиктивного датчика в ваш комплект в начале дня, прежде чем вы начнете свой расчет.

Дополнительные записи добавляются:

0, '2016-04-01 00:00:00' 
1, '2016-04-01 00:00:00' -- This is conditional on the first record in your set having a value of 1 

Общий запрос ниже
Примечание: для того, чтобы определить, какая запись является фактически первым в последовательности я использовал столбец «ID».

;WITH Q0 AS(
    -- Inserts a new record (0, '2016-04-01 00:00:00') to the beginning of the day 
    SELECT TOP 1 0 AS Value, CONVERT(DATETIME, CONVERT(DATE, LogDate)) AS LogDate 
    FROM #SwitchLog 
    UNION ALL 
    -- Inserts a new record (1, '2016-04-01 00:00:00') to the beginning of the day when the first record has Value = 1 
    SELECT Value, CONVERT(DATETIME, CONVERT(DATE, LogDate)) AS LogDate 
    FROM 
     (SELECT TOP 1 ID, Value, LogDate 
     FROM #SwitchLog 
     ORDER BY LogDate ASC, ID ASC) AS DummyRecord --<-- NOTE: the use of a table ID column 
    WHERE Value = 1 
    UNION ALL 
    SELECT Value, LogDate 
    FROM #SwitchLog 
) 
, 
Q1 AS (SELECT ROW_NUMBER() OVER (ORDER BY LogDate) AS id, 
SUM(Value) AS Value, LogDate 
FROM Q0 
GROUP BY LogDate 
HAVING COUNT(LogDate) > 1) 

SELECT A.Value, DATEDIFF(SECOND,A.LogDate,B.LogDate) AS Total 
FROM Q1 AS A 
INNER JOIN Q1 AS B 
ON B.ID = A.ID + 1 AND B.ID%2 = 0 

Выход:

Value  Total 
----------- ----------- 
1   69 
1   1782 
1   1782 

Тот же подход должен быть использован, чтобы вставить фиктивную запись (ы) в конце периода/день ((день + 1) 00:00:00), чтобы удовлетворить для случаев, когда значение датчика равно 1 в конце дня.

+0

Это сработало, спасибо. – Jorge

+0

@Jorge, давайте посмотрим, сможет ли кто-нибудь другой ответить на лучший ответ, если ничего не придет, отметьте ответ как принятый. – Alex

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