U kunt dit doen met behulp van group by met het gewenste niveau. Hier is een voorbeeld met de gegevens die je hebt gegeven:
Eerst de SQL om de tabel aan te maken en te vullen. De ID-kolom hier is niet "nodig", maar het wordt aanbevolen als de tabel groot is of indexen bevat.
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');
Om een lijst van bestelde paren van aantal minuten tot aantal evenementen te krijgen:
De query kan dan eenvoudig worden geschreven met behulp van de timestampdiff-functie, zoals hieronder weergegeven:
SELECT
TIMESTAMPDIFF(MINUTE, start, end) as minutes,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(MINUTE, start, end)
De uitvoer:
minutes numEvents
3 3
5 1
De eerste parameter in de selectie kan FRAC_SECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER of YEAR zijn.
Hier zijn nog enkele voorbeelden van zoekopdrachten die u kunt uitvoeren:
Evenementen per uur (etagefunctie is toegepast)
SELECT
TIMESTAMPDIFF(HOUR, start, end) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
**Evenementen per uur met betere opmaak **
SELECT
CONCAT("<", TIMESTAMPDIFF(HOUR, start, end) + 1) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
U kunt groeperen op verschillende opties, maar dit zou u zeker op weg moeten helpen. Bij de meeste plotpakketten kunt u willekeurige x y-coördinaten opgeven, zodat u zich geen zorgen hoeft te maken over de ontbrekende waarden op de x-as.
Om een lijst met geordende paren van het aantal gebeurtenissen op een specifiek tijdstip te krijgen (voor logboekregistratie): Merk op dat dit ter referentie wordt achtergelaten.
Nu voor de vragen. Eerst moet je kiezen welk item je wilt gebruiken voor de groepering. Een taak kan bijvoorbeeld meer dan een minuut duren, dus het begin en einde zijn in verschillende minuten. Voor al deze voorbeelden baseer ik ze op de starttijd, aangezien het evenement toen daadwerkelijk plaatsvond.
Om het aantal gebeurtenissen per minuut te groeperen, kunt u een zoekopdracht als deze gebruiken:
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);
Merk op hoe dit groepeert op alle items, beginnend met jaar, tot op de minuut. Ik heb ook de minuut weergegeven als een label. De resulterende uitvoer ziet er als volgt uit:
minute numEvents
January 1, 2015 12:00 PM 1
January 1, 2015 12:03 PM 3
Dit zijn gegevens die je vervolgens met php zou kunnen nemen en voorbereiden voor weergave door een van de vele grafische bibliotheken die er zijn, waarbij de minuutkolom op de x-as wordt geplot en de numEvents op de y-as wordt geplot.
Hier zijn nog enkele voorbeelden van zoekopdrachten die u kunt uitvoeren:
Evenementen per uur
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);
Evenementen op datum
SELECT
DATE_FORMAT(start, '%M %e, %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start);
Evenementen per maand
SELECT
DATE_FORMAT(start, '%M %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start);
Evenementen per jaar
SELECT
DATE_FORMAT(start, '%Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start);
Ik moet er ook op wijzen dat als je een index in de startkolom voor deze tabel hebt, deze zoekopdrachten snel zullen worden voltooid, zelfs met honderden miljoenen rijen.
Ik hoop dat dit helpt! Laat het me weten als je hier nog vragen over hebt.