MySQL Select каждой n-ой строки

Друзья, подскажите пожалуйста.
Есть таблица с тремя полями — id (auto_increment), date(timestamp) и value.
Каждые 10 секунд в БД добавляется одна запись value. Остальные поля прописываются автоматически.

Необходимо построить графики за час, сутки и тп…
Для построения графика за час необходимо выбрать 60 записей из 360. То есть берется одно значение за каждую минуту (каждое 6). Соответственно за сутки — 24 записи из 8640 (каждое 360). Ну и так далее…

Можно ли такой запрос реализовать средствами MySQL используя id или дату?
  • Вопрос задан
  • 10091 просмотр
Решения вопроса 1
@Horzerus
Если требуется прорядить данные, то можно использовать группировку по формату поля даты:

Например, для группировки по минутам:
GROUP BY DATE_FORMAT (`date`, "%y-%m-%d-%H-%i")
"%y%j%H-%i" — тоже самое, но так быстрее будет.
Ответ написан
Пригласить эксперта
Ответы на вопрос 10
AlexeyK
@AlexeyK
А каким образом вы собираетесь строить график по каждому 6му значению, если у вас 6 разных (наверное?) значений, а вы будете брать всего одно (даже не среднее арифметическое)?
Ответ написан
Комментировать
AlexXYZ
@AlexXYZ
O Keep Clear O
select * from tbl where id%10=0 and datetime>=addtime(now(), '-0:1:00');

Выбрать данные за последнюю минуту, в которых id кретен 10. За сутки что-то похожее будет.
Ответ написан
Комментировать
Dzuba
@Dzuba
Поскольку такая таблица может иметь весьма приличный объем, отчего неизбежно пострадает скорость, я бы советовал реализовать всю логику в момент вставки новой записи, а именно:
1. Создать доп. таблицы для записей часа, суток и т.д., в которых хранить только записи за соответствующие моменты времени. Тогда доступ к ним будет весьма быстрым. Правда объем еще увеличится.
2. Если есть доступ к ПО, которое осуществляет запись в БД, проверять в нем величину соответствующего интервала. Если нет, или если требование «реализовать средствами MySQL» принципиально, то использовать триггер на вставку в исходную таблицу, в котором проверять условие и дублировать запись в таблицы для часа, суток и т.д.
При этом в доп.таблицы достаточно вставлять не саму запись, а только ее id.
Ответ написан
Комментировать
lashtal
@lashtal
Каждую n-ную выбрать так (пример для каждой 60-й):

SELECT @row := @row + 1 row, t.id
FROM table t, (SELECT @row := 0) row
GROUP BY t.id
HAVING row % 60 = 0

Проблема очевидна: идет выборка всех строк, и далее фильтрация по having. Да, по индексу все должно работать быстро и фильтрация на уровне бд будет быстрее, чем на используемом яп, но это явно не то.

На mysql это делать неверно, есть православный rrdtool, который и предназначен для работы с последовательностями значений во времени, автоматом получая данные в разрезе некоторого времени (напр. сутки, неделя, месяц, год).
Ответ написан
Комментировать
@Jazzist
Решение 1. Минутный timestamp нацело делится на 60? Можно написать условие сравнения для MySQL.

Решение 2. Есть-ли возможность писать дополнительный ключ? Если да — значит существует еще одно ресурсоэкономное решение.
Ответ написан
Комментировать
rvller
@rvller
Выбрать все записи за нужный промежуток и уже из них, как сказано выше, считать средне арифметическое из нескольких значений, что и будет являться точкой графика.
Ответ написан
taliban
@taliban
php программист
Судя по задаче данных у Вас будет очень много. Я бы советовал добавить полей и ими оперировать
То есть, если значения времени в записях БД выглядят так:

22:19:00
22:19:10
22:19:20
22:19:30
22:19:40
22:19:50
22:20:00
22:20:10

то мы берем только
22:19:00
22:20:00


Тут лайк сдохнет, стоит добавить поле «00 ли в конце?» и выбирать по нему.
Опять де если выборка по датам, то даты разбить на части и по этим частям выбирать.
Эти варианты более зромоздкие, но скорости прибавить точно.
Ответ написан
@Scioner
select field1, field2 from table
where mod(id, 60)=0

select field1, field2 from table
where mod(id, 360)=0

select field1, field2 from table
where mod(id, 1880)=0

etc…
Ответ написан
lumenous
@lumenous Автор вопроса
Перефразирую точнее…
Значение value — показание температуры.
При построении часового графика необходимо 60 показаний. Из БД мы берем одно значение за каждую минуту этого часа.
То есть, если значения времени в записях БД выглядят так:

22:19:00
22:19:10
22:19:20
22:19:30
22:19:40
22:19:50
22:20:00
22:20:10

то мы берем только
22:19:00
22:20:00

То что произошло за эту минуту можно не учитывать.
Ответ написан
AlexXYZ
@AlexXYZ
O Keep Clear O
Про rrdtools мне очень понравилось. Достаточно быстро нашёл ссылку: Использование rrdtool для мониторинга сети. Мега вещь!!! Не знал. Спасибо за наводку.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы