SQL Подсчет событий с продолжительностью в час - PullRequest
0 голосов
/ 19 января 2020

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

Event     |   Start Time    |   End Time
-----------------------------------------
  1       |   12:03         |   14:20
  2       |   12:30         |   12:50
  3       |   13:05         |   14:45
  4       |   14:01         |   14:49

У меня также есть «Продолжительность», доступная в качестве альтернативы «Время окончания». Результат, который я ищу, будет выглядеть так:

  Hour     |     Count
-----------------------
   12      |     2
   13      |     2
   14      |     3

В течение 12-го часа произошло два события (1 и 2), в 13-м часе также было два события (1 и 3) и 14-й час было три события (1, 3 и 4).

Я могу сделать это программно с помощью al oop. Я могу сосчитать, когда события start (или end ) в SQL. Но мне бы очень хотелось сократить разрыв и сделать это в SQL, но я не могу придумать способ.

Ответы [ 3 ]

1 голос
/ 19 января 2020

Одно из возможных решений (работает с MySQL v5.6 + и SQLite3):

create table hours(Hour int);
insert into hours values
  (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),
  (13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23);

create table log(Event int,StartTime varchar(5),EndTime varchar(5));
insert into log values
  (1,'12:03','14:20'),
  (2,'12:30','12:50'),
  (3,'13:05','14:45'),
  (4,'14:01','14:49');

-- ------------------------------------------------------------------------------

select Hour,count(Event) Count
  from log join hours
    on Hour between substr(StartTime,1,2) and substr(EndTime,1,2)
  group by Hour;
1 голос
/ 19 января 2020

Если у вас нет MySql 8, то создайте таблицу hour:

CREATE TABLE hour (
  hr INT PRIMARY KEY
);

INSERT INTO hour(hr) VALUES
    (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),
    (12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23);

А затем:

select h.hr, count(*) as cnt from hour h
join mytable m on h.hr between hour(m.Start_Time) and hour(m.End_Time)
group by hr
order by hr
;

См. Db-Fiddle

1 голос
/ 19 января 2020

Если вы используете MySQL 8.0, вы можете использовать UNION ALL, оконные функции и агрегирование, например:

select hr, sum(sum(cnt)) over(order by hr) cnt
from (
    select hour(start_time) hr, 1 cnt from mytable
    union all select hour(end_time) + 1, -1 from mytable
) t
group by hr

Демонстрация на DB Fiddle :

hr | cnt
-: | --:
12 |   2
13 |   2
14 |   3
15 |   0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...