Использование запроса MySQL для регулярного подсчета записей с временными диапазонами - PullRequest
0 голосов
/ 27 мая 2020

Учитывая таблицу MySQL, которая отслеживает, сколько времени посетитель провел в определенном месте, какой запрос будет подходящим для подсчета общего количества посетителей с 5-минутными интервалами в течение дня?

+-----------------+------------------+------+-----+---------+-------+
| Field           | Type             | Null | Key | Default | Extra |
+-----------------+------------------+------+-----+---------+-------+
| end_timestamp   | int(10) unsigned | NO   | PRI | NULL    |       |
| start_timestamp | int(10) unsigned | NO   | PRI | NULL    |       |
| visitor_id      | int(10) unsigned | NO   | PRI | NULL    |       |
| location_id     | int(10) unsigned | NO   | PRI | NULL    |       |
+-----------------+------------------+------+-----+---------+-------+

Например, результаты могут выглядеть так:

+---------------------+-------------------+
| Timestamp           | COUNT(visitor_id) |
+---------------------+-------------------+
| 2020-01-01 00:00:00 | 45                |
| 2020-01-01 00:05:00 | 49                |
| 2020-01-01 00:10:00 | 37                |
...

Это то, что я сейчас вычисляю после запроса, но хочу переложить часть работы на сервер MySQL, выполняя это как часть базы данных. запрос.

1 Ответ

2 голосов
/ 27 мая 2020

Если вы используете MySQL 8.0, вы можете использовать рекурсивный запрос для генерации интервалов, затем привести свою таблицу с left join и, наконец, агрегировать.

Следующий запрос дает вам информацию который вы хотите для текущего дня (вы можете изменить current_date на другую дату по мере необходимости):

with all_ts as (
    select current_date ts
    union all
    select ts + interval 5 minute 
    from all_ts 
    where ts < current_date + interval 1 day
)
select a.ts, count(t.visitor_id) no_visitors
from all_ts a
left join mytable t
    on  t.start_timestamp >= a.ts
    and t.end_timestamp   <  a.ts 
group by a.ts

Если вы сохраняете свои даты как unix метки времени, вы можете изменить left join следующим образом:

left join mytable t
    on  t.start_timestamp >= unix_timestamp(a.ts)
    and t.end_timestamp   <  unix_timestamp(a.ts)
...