[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Группировка за временной период
wasabi
Всем доброго времени суток.

БД на mssql 2008, есть табличка с тремя полями: id / value / valuedate.
Данных в таблице много и временной промежуток между ними примерно в 30 секунд.
Необходимо выполнить select к таблице и вернуть усредненное value с периодом по 6 часов.

На данный момент есть скрипт усредняющий value по 1 часу:

SELECT ROUND(AVG(value), 2) AS value, DATEPART(hour, convert(varchar, cast(valuedate AS datetime), 121)) AS valuedate
FROM history where id=4210
AND valuedate>='04.05.2012 00:00'
AND valuedate<='05.05.2012 00:00'
GROUP BY DATEPART(hour, convert(varchar, cast(valuedate AS datetime), 121))
ORDER BY valuedate ASC


Собственно кто подскажет как задать этот 6-ти часовой интервал? :)



Спустя 2 часа, 47 минут, 55 секунд (4.05.2012 - 17:51) ilma55 написал(а):
вообще не понял вопроса. конкретнее

Спустя 12 часов, 8 минут, 26 секунд (5.05.2012 - 05:59) wasabi написал(а):
ilma55
На данный момент скрипт выгребает из таблицы данные в этом диапазоне AND valuedate>='04.05.2012 00:00' AND valuedate<='05.05.2012 00:00', строк там тысячи, такое меня не устраивает, написал скрипт который в первом посту, он все выгребаемые данные групирует по часам и усредняет. В итоге у меня на выходе 24 строки, по количеству часов в сутки, НО мне необходимо групировать строки по 6 часов, чтобы в итоге получилось 4 строки за 1 сутки.
Вот так вроде ооочень конкретно =)

Спустя 4 часа, 24 минуты, 4 секунды (5.05.2012 - 10:23) sergeiss написал(а):
Цитата (wasabi @ 4.05.2012 - 15:03)
Собственно кто подскажет как задать этот 6-ти часовой интервал?

Ответ содержится в вопросе :) Надо задать этот интервал.

А именно, создай в выборке поле, величина которого определяется этими 6-часовыми интервалами. В Мускуле есть деление по модулю, его и используй.
select ......, N%6 as part_6

где N - номер часа внутри дня. Правда я не понял, зачем строить такие 16-этажные выражения с DATEPART? Почему бы не взять функцию HOUR()?

Спустя 38 минут, 14 секунд (5.05.2012 - 11:02) wasabi написал(а):
sergeiss
Вы пишите про мускул, я же использую БД на mssql 2008.

Более точной наводки дать не можете? На пример какой нибудь?=)

Спустя 43 минуты, 24 секунды (5.05.2012 - 11:45) sergeiss написал(а):
Кстати говоря, тебе надо не деление по модулю, а целую часть от деления на 6! В любом языке это легко делается, примерно так:
(int) hour/6.0

Не знаю точно, как это будет в MSSQL, но очень близко к написанному мной.

Спустя 5 дней, 28 минут, 30 секунд (10.05.2012 - 12:14) wasabi написал(а):
Решение моего вопроса:
declare @d datetime  = '20120305'

; with d as (
select d1 = @d, d2 = dateadd(hh, 6, @d)
union all
select
d1 = d.d2, d2 = dateadd(hh, 6, d2)
from d
where d.d2 < dateadd(dd, 1, @d)

)

select d.d1, h.value
from d
cross apply (
SELECT ROUND(AVG(value), 2) AS value
FROM history
where id=4210
AND valuedate >=d.d1
AND valuedate < d.d2

) h

Спустя 1 час, 32 минуты, 26 секунд (10.05.2012 - 13:46) sergeiss написал(а):
Цитата (wasabi @ 10.05.2012 - 12:14)
Решение моего вопроса:

Может быть это и решение твоего вопроса, но я сколько ни "втыкал", но так и не понял, как тут получается усреднение по 6 часов? Или ты это запрос используешь как в вложенный для другого запроса, где уже есть группировка?

PS. Вот в Постгре так можно сделать:
select date_, h/6 as part_6 , sum(mc01), avg(mc01)
from stat_alc_bts
where lac between 2800 and 2819 and cellid=1101 and date_ between '2012-03-01' and '2012-03-07' and h<24
group by date_, part_6
order by date_, part_6

Делается запрос к статистике, уникальные объекты выбираются по параметрам lac, cellid, время (h) лежит в интревале от 0 до 24, где 24 - сумма за день. mc01 - счетчик статистики, один из многих в этой таблице. Вместо mc01 или вместе с ним я могу использовать и другие счетчики, вместе с агрегирующими функциями.
В запросе я выбираю только часовые данные определенного объекта, за 7 дней, и группирую их по интервал 6 часов. Всё ясно, понятно и прозрачно. В MSSQL можно также сделать - так почему бы не сделать? Только вместо h (часа), уже известного в моем случае, надо будет взять функцию datepart(), чтобы получить час "в чистом виде".

PPS. Собственно говоря, мой запрос очень похож на твой начальный. Тебе надо было только избавиться от какого-то непонятного, многоэтажного преобразования дат и добавить нахождение номера 6-часовой части внути дня (как в моем запросе).
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.