Группировать по интервалу времени, включая начало следующего?

#mysql #sql #time

#mysql #sql #время

Вопрос:

Я пытаюсь создать запрос, который группирует мои данные по временному интервалу (т.Е. 30 минут), а затем вычисляет разницу между первой и последней строкой в каждой группе.

select (max(v) - min(v)) as x, from_unixtime(FLOOR(UNIX_TIMESTAMP(d)/(30*60))*(30*60)) as timeKey from y group by timeKey

Приведенное выше корректно возвращает мои данные в 30-минутных фрагментах, однако мне нужно как-то настроить его, чтобы включить все между 12:00 and 12:30 , а не 12:00 and 12:29 .

Я пытался использовать следующее, однако max его нельзя использовать при присвоении значения.

select max(v) - @lastV, from_unixtime(FLOOR(UNIX_TIMESTAMP(d)/(30*60))*(30*60)) as timeKey, @lastv := v from `test`, (select @lastV:=0) lastV group by timeKey

http://sqlfiddle.com /#!9/e8d74/4

Я создал вышеупомянутую SQL-скрипку с некоторыми данными, которые можно использовать в качестве примера.

У кого-нибудь есть какие-либо предложения?

Комментарии:

1. Тогда вы получите повторяющиеся записи. 12:30 будет как в 12:00-12:30 , так и 12:30 - 13:00 . В каком из них вы этого хотите?

2. @sagi — извините, чувствую, что не ответил должным образом — я пытаюсь воспроизвести процесс, который в настоящее время обрабатывается с помощью кода, который перебирает интервалы и выполняет запрос, т. Е. (select max(v) - min(v) as usage from 'test' where d between '2016-01-01 12:00' and '2016-01-01 12:30' . Помогает ли это?

Ответ №1:

Потенциальное решение, которое мне удалось придумать сегодня утром:

select *, IF(@lastV, @lastV - minV, 0) as `usage`, @lastV := minV from (
select min(v) as minV, max(v) as maxV, from_unixtime(FLOOR(UNIX_TIMESTAMP(d)/(30*60))*(30*60)) as timeKey from `test` group by timeKey order by timeKey desc
) items, (select @lastV:=0) lastV

http://sqlfiddle.com /#!9/e8d74/18/0

К сожалению, это работает только при сортировке по убыванию и создает избыточную строку (первой строке не с чем сравнивать), однако, основываясь на моих тестах, эта строка не требуется и может быть проигнорирована при чтении данных.

Было бы полезно, если бы у кого-нибудь были какие-либо другие решения?