Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Histograma de consulta MySql para dados de intervalos de tempo


Você pode fazer isso usando group by com o nível desejado. Aqui está um exemplo usando os dados que você forneceu:

Primeiro o SQL para criar a tabela e preenchê-la. A coluna ID aqui não é "necessária", mas é recomendada se a tabela for grande ou tiver índices nela.
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 obter uma lista de pares ordenados do número de minutos de duração para o número de eventos:

A consulta pode ser facilmente escrita usando a função timestampdiff, conforme mostrado abaixo:
SELECT 
    TIMESTAMPDIFF(MINUTE, start, end) as minutes,
    COUNT(*) AS numEvents
FROM
    test.events
GROUP BY TIMESTAMPDIFF(MINUTE, start, end)

A saída:
minutes      numEvents
3            3
5            1

O primeiro parâmetro na seleção pode ser FRAC_SECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER ou YEAR.

Aqui estão mais alguns exemplos de consultas que você pode fazer:

Eventos por hora (função de piso é aplicada)
SELECT 
    TIMESTAMPDIFF(HOUR, start, end) as hours,
    COUNT(*) AS numEvents
FROM
    test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)

**Eventos por hora com melhor formatação**
SELECT 
    CONCAT("<", TIMESTAMPDIFF(HOUR, start, end) + 1) as hours,
    COUNT(*) AS numEvents
FROM
    test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)

Você pode agrupar por uma variedade de opções, mas isso definitivamente deve começar. A maioria dos pacotes de plotagem permitirá que você especifique coordenadas x y arbitrárias, então você não precisa se preocupar com os valores ausentes no eixo x.

Para obter uma lista de pares ordenados do número de eventos em um horário específico (para registro): Observe que isso é deixado para referência.

Agora para as consultas. Primeiro você precisa escolher qual item deseja usar para o agrupamento. Por exemplo, uma tarefa pode levar mais de um minuto, então o início e o fim seriam em minutos diferentes. Para todos esses exemplos, estou baseando-os na hora de início, pois foi quando o evento realmente ocorreu.

Para agrupar contagens de eventos por minuto, você pode usar uma 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 como isso agrupa por todos os itens, começando com o ano, indo a cada minuto. Eu também tenho o minuto exibido como um rótulo. A saída resultante se parece com isso:
minute                      numEvents
January 1, 2015 12:00 PM    1
January 1, 2015 12:03 PM    3

Esses são os dados que você pode pegar usando php e prepará-los para exibição por uma das muitas bibliotecas gráficas existentes, plotando a coluna de minuto no eixo x e plotando os numEvents no eixo y.

Aqui estão mais alguns exemplos de consultas que você pode fazer:

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 data
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 mês
SELECT 
    DATE_FORMAT(start, '%M %Y') as date, 
    count(*) AS numEvents 
FROM test.events 
GROUP BY YEAR(start), MONTH(start);

Eventos por ano
SELECT 
    DATE_FORMAT(start, '%Y') as date, 
    count(*) AS numEvents 
FROM test.events 
GROUP BY YEAR(start);

Também devo salientar que, se você tiver um índice na coluna inicial dessa tabela, essas consultas serão concluídas rapidamente, mesmo com centenas de milhões de linhas.

Espero que isto ajude! Deixe-me saber se você tiver quaisquer outras perguntas sobre isso.