Puede hacer esto usando group by con el nivel que desee. Aquí hay un ejemplo usando los datos que proporcionó:
Primero el SQL para crear la tabla y llenarla. La columna ID aquí no es "necesaria", pero se recomienda si la tabla será grande o tendrá índices.
CREATE TABLE `test`.`events` (
`id` INT NOT NULL AUTO_INCREMENT,
`user` INT NULL,
`start` DATETIME NULL,
`end` DATETIME NULL,
`type` VARCHAR(45) NULL,
PRIMARY KEY (`id`));
INSERT INTO events (user, start, end, type) VALUES
(1, '2015-1-1 12:00:00', '2015-1-1 12:03:59', 'browsing'),
(2, '2015-1-1 12:03:00', '2015-1-1 12:06:00', 'browsing'),
(2, '2015-1-1 12:03:00', '2015-1-1 12:06:00', 'eating'),
(3, '2015-1-1 12:03:00', '2015-1-1 12:08:00', 'browsing');
Para obtener una lista de pares ordenados de número de minutos de duración a número de eventos:
La consulta se puede escribir fácilmente usando la función timestampdiff, como se muestra a continuación:
SELECT
TIMESTAMPDIFF(MINUTE, start, end) as minutes,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(MINUTE, start, end)
La salida:
minutes numEvents
3 3
5 1
El primer parámetro en la selección puede ser FRAC_SECOND, SEGUNDO, MINUTO, HORA, DÍA, SEMANA, MES, TRIMESTRE o AÑO.
Aquí hay algunos ejemplos más de consultas que puede hacer:
Eventos por hora (se aplica la función de piso)
SELECT
TIMESTAMPDIFF(HOUR, start, end) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
**Eventos por hora con mejor formato **
SELECT
CONCAT("<", TIMESTAMPDIFF(HOUR, start, end) + 1) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
Puede agrupar por una variedad de opciones, pero esto definitivamente debería ayudarlo a comenzar. La mayoría de los paquetes de trazado le permitirán especificar coordenadas x y arbitrarias, por lo que no necesita preocuparse por los valores que faltan en el eje x.
Para obtener una lista de pares ordenados de cantidad de eventos en un momento específico (para registro): Tenga en cuenta que esto se deja como referencia.
Ahora las consultas. Primero debe elegir qué elemento desea utilizar para la agrupación. Por ejemplo, una tarea puede tardar más de un minuto, por lo que el inicio y el final estarían en minutos diferentes. Para todos estos ejemplos, los estoy basando en la hora de inicio, ya que es cuando realmente tuvo lugar el evento.
Para agrupar recuentos de eventos por minuto, puede utilizar una consulta como esta:
SELECT
DATE_FORMAT(start, '%M %e, %Y %h:%i %p') as minute,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start), HOUR(start), MINUTE(start);
Observe cómo esto agrupa por todos los elementos, comenzando con el año y siguiendo con el minuto. También tengo el minuto mostrado como una etiqueta. El resultado resultante se ve así:
minute numEvents
January 1, 2015 12:00 PM 1
January 1, 2015 12:03 PM 3
Estos son datos que luego podría tomar usando php y prepararlos para mostrarlos en una de las muchas bibliotecas de gráficos que existen, trazando la columna de minutos en el eje x y trazando el número de eventos en el eje y.
Aquí hay algunos ejemplos más de consultas que puede hacer:
Eventos por hora
SELECT
DATE_FORMAT(start, '%M %e, %Y %h %p') as hour,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start), HOUR(start);
Eventos por fecha
SELECT
DATE_FORMAT(start, '%M %e, %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start);
Eventos por mes
SELECT
DATE_FORMAT(start, '%M %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start);
Eventos por año
SELECT
DATE_FORMAT(start, '%Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start);
También debo señalar que si tiene un índice en la columna de inicio de esta tabla, estas consultas se completarán rápidamente, incluso con cientos de millones de filas.
¡Espero que esto ayude! Avíseme si tiene alguna otra pregunta sobre esto.