Puoi farlo usando il gruppo per con il livello che desideri. Ecco un esempio utilizzando i dati che hai fornito:
Prima l'SQL per creare la tabella e popolarla. La colonna ID qui non è "necessaria", ma è consigliata se la tabella è grande o contiene indici.
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');
Per ottenere un elenco di coppie ordinate da numero di minuti durata a numero di eventi:
La query può quindi essere facilmente scritta utilizzando la funzione timestampdiff, come mostrato di seguito:
SELECT
TIMESTAMPDIFF(MINUTE, start, end) as minutes,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(MINUTE, start, end)
L'uscita:
minutes numEvents
3 3
5 1
Il primo parametro nella selezione può essere uno di FRAC_SECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER o YEAR.
Ecco altri esempi di query che puoi eseguire:
Eventi per ora (viene applicata la funzione floor)
SELECT
TIMESTAMPDIFF(HOUR, start, end) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
**Eventi per ora con una migliore formattazione **
SELECT
CONCAT("<", TIMESTAMPDIFF(HOUR, start, end) + 1) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
Puoi raggruppare in base a una varietà di opzioni, ma questo dovrebbe sicuramente iniziare. La maggior parte dei pacchetti di stampa ti consentirà di specificare coordinate x y arbitrarie, quindi non devi preoccuparti dei valori mancanti sull'asse x.
Per ottenere un elenco di coppie ordinate di numero di eventi in un momento specifico (per la registrazione): Nota che questo è lasciato come riferimento.
Ora per le domande. Per prima cosa devi scegliere quale elemento desideri utilizzare per il raggruppamento. Ad esempio, un'attività potrebbe richiedere più di un minuto, quindi l'inizio e la fine sarebbero in minuti diversi. Per tutti questi esempi, li sto basando sull'ora di inizio, poiché è lì che si è effettivamente verificato l'evento.
Per raggruppare i conteggi degli eventi per minuto, puoi utilizzare una query come questa:
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);
Nota come questo raggruppa per tutte le voci, a partire dall'anno, andando al minuto. Ho anche il minuto visualizzato come etichetta. L'output risultante è simile al seguente:
minute numEvents
January 1, 2015 12:00 PM 1
January 1, 2015 12:03 PM 3
Questi sono i dati che potresti quindi prendere usando php e prepararli per la visualizzazione da parte di una delle tante librerie di grafici disponibili, tracciando la colonna dei minuti sull'asse x e tracciando i numEvents sull'asse y.
Ecco altri esempi di query che puoi eseguire:
Eventi per ora
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);
Eventi per data
SELECT
DATE_FORMAT(start, '%M %e, %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start);
Eventi per mese
SELECT
DATE_FORMAT(start, '%M %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start);
Eventi per anno
SELECT
DATE_FORMAT(start, '%Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start);
Vorrei anche sottolineare che se hai un indice nella colonna iniziale di questa tabella, queste query verranno completate rapidamente, anche con centinaia di milioni di righe.
Spero che sia di aiuto! Fammi sapere se hai altre domande a riguardo.