sql >> Database >  >> RDS >> Mysql

MySql-queryhistogram voor gegevens over tijdsintervallen

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.



  1. PHP recursieve functie om alle onderliggende nodes te verwijderen veroorzaakt stackoverflow

  2. Pharo Smalltalk en mySql

  3. Doctrine 2 SUM() equivalente helper?

  4. PDO doorlussen en fetchAll afdrukken