У меня есть следующая таблица в выпуске SQL Server Express:
Time Device Value
0:00 1 2
0:01 2 3
0:03 3 5
0:03 1 3
0:13 2 5
0:22 1 7
0:34 3 5
0:35 2 6
0:37 1 5
Таблица используется для регистрации событий различных устройств, которые сообщают свои последние значения. Я хотел бы подготовить данные таким образом, чтобы я представлял средние данные по шкале времени и в конечном итоге создавал диаграмму, используя эти данные. Я манипулировал данными этого примера в Excel следующим образом:
Time Average value
0:03 3,666666667
0:13 4,333333333
0:22 5,666666667
0:34 5,666666667
0:35 6
0:37 5,333333333
Итак, во время 0:03 мне нужно взять последние данные, которые у меня есть в таблице, и вычислить среднее значение. В этом случае это (3 + 3 + 5) / 3 = 3,67. Во время 0:13 шаги будут повторяться, и снова в 0:22, ...
Поскольку я хотел бы оставить все в таблице SQL (я бы не хотел создавать какой-либо сервис с C # или аналогичным, который бы захватывал данные и сохранял их в какой-то другой таблице)
Я бы хотел знать следующее:
- это правильный подход или я должен использовать какую-то другую концепцию расчета среднего значения для подготовки данных графика?
- если да, каков наилучший подход для его реализации? Табличное представление, функция в базе данных, хранимая процедура (которая будет вызвана из API построения диаграмм)?
- какие-либо предложения о том, как это реализовать?
Заранее спасибо.
Mark
Обновление 1
Тем временем у меня появилась идея, как подойти к этой проблеме. Я хотел бы попросить вас прокомментировать это, и мне все еще нужна помощь в решении проблемы.
Итак, идея состоит в том, чтобы создать перекрестную таблицу следующим образом:
Time Device1Value Device2Value Device3Value
0:00 2 NULL NULL
0:01 NULL 3 NULL
0:03 3 NULL 5
0:13 NULL 5 NULL
0:22 7 NULL NULL
0:34 NULL NULL 5
0:35 NULL 6 NULL
0:37 5 NULL NULL
Запрос для этого должен быть:
SELECT Time,
(SELECT Stock FROM dbo.Event WHERE Time = S.Time AND Device = 1) AS Device1Value,
(SELECT Stock FROM dbo.Event WHERE Time = S.Time AND Device = 2) AS Device2Value,
(SELECT Stock FROM dbo.Event WHERE Time = S.Time AND Device = 3) AS Device3Value
FROM dbo.Event S GROUP BY Time
Что мне еще нужно сделать, так это написать пользовательскую функцию и вызвать ее в этом запросе, который записал бы последнее доступное значение в случае NULL, а если бы последнее доступное значение не существовало, оно оставило бы значение NULL. С помощью этой функции я получил бы следующие результаты:
Time Device1Value Device2Value Device3Value
0:00 2 NULL NULL
0:01 2 3 NULL
0:03 3 3 5
0:13 3 5 5
0:22 7 5 5
0:34 7 5 5
0:35 7 6 5
0:37 5 6 5
И, имея эти результаты, я смогу рассчитать среднее значение для каждого времени, только суммируя 3 релевантных столбца и деля его на количество (в данном случае 3). Для NULL я бы использовал значение 0.
Кто-нибудь может подсказать, как создать пользовательскую функцию для замены значений NULL на последнее значение?
Обновление 2
Спасибо, Мартин.
Этот запрос работал, но для прохождения 13.576 строк потребовалось почти 21 минута, что слишком много.
Последний запрос, который я использовал, был:
SELECT Time,
(SELECT TOP 1 Stock FROM dbo.Event e WHERE e.Time <= S.Time AND Device = 1 ORDER BY e.Time DESC) AS Device1Value,
(SELECT TOP 1 Stock FROM dbo.Event e WHERE e.Time <= S.Time AND Device = 2 ORDER BY e.Time DESC) AS Device2Value,
(SELECT TOP 1 Stock FROM dbo.Event e WHERE e.Time <= S.Time AND Device = 3 ORDER BY e.Time DESC) AS Device3Value
FROM dbo.Event S GROUP BY Time
но я расширил его до 10 устройств.
Я согласен, что это не лучший способ сделать это. Есть ли другой способ подготовить данные для вычисления среднего, потому что это занимает слишком много времени для обработки.