J'essaie de regrouper certains enregistrements en intervalles de 5, 15, 30 et 60 minutes:
SELECT AVG(value) as "AvgValue",
sample_date/(5*60) as "TimeFive"
FROM DATA
WHERE id = 123 AND sample_date >= 3/21/2012
je veux exécuter plusieurs requêtes, chacune regrouperait mes valeurs moyennes dans les incréments de temps souhaités. Ainsi, la requête de 5 minutes retournerait des résultats comme celui-ci:
AvgValue TimeFive
6.90 1995-01-01 00:05:00
7.15 1995-01-01 00:10:00
8.25 1995-01-01 00:15:00
La requête de 30 minutes entraînerait ceci:
AvgValue TimeThirty
6.95 1995-01-01 00:30:00
7.40 1995-01-01 01:00:00
La colonne datetime
est dans yyyy-mm-dd hh:mm:ss
format
Je reçois des erreurs de conversion implicites de ma colonne datetime
. Toute aide est très appréciée!
En utilisant
datediff(minute, '1990-01-01T00:00:00', yourDatetime)
vous donnera le nombre de minutes depuis le 1990-1-1 (vous pouvez utiliser la date de base souhaitée).
Ensuite, vous pouvez diviser par 5, 15, 30 ou 60 et regrouper par le résultat de cette division. J'ai vérifié qu'il sera évalué comme une division entière, vous obtiendrez donc un nombre entier que vous pouvez utiliser pour vous regrouper.
c'est à dire.
group by datediff(minute, '1990-01-01T00:00:00', yourDatetime) /5
UPDATE Comme la question d'origine a été modifiée pour exiger que les données soient affichées au format date-heure après le regroupement, j'ai ajouté cette requête simple qui fera l'affaire ce que le PO veut:
-- This convert the period to date-time format
SELECT
-- note the 5, the "minute", and the starting point to convert the
-- period back to original time
DATEADD(minute, AP.FiveMinutesPeriod * 5, '2010-01-01T00:00:00') AS Period,
AP.AvgValue
FROM
-- this groups by the period and gets the average
(SELECT
P.FiveMinutesPeriod,
AVG(P.Value) AS AvgValue
FROM
-- This calculates the period (five minutes in this instance)
(SELECT
-- note the division by 5 and the "minute" to build the 5 minute periods
-- the '2010-01-01T00:00:00' is the starting point for the periods
datediff(minute, '2010-01-01T00:00:00', T.Time)/5 AS FiveMinutesPeriod,
T.Value
FROM Test T) AS P
GROUP BY P.FiveMinutesPeriod) AP
REMARQUE: J'ai divisé cela en 3 sous-requêtes pour plus de clarté. Vous devriez le lire de l'intérieur. Il pourrait, bien sûr, être écrit comme une seule requête compacte
REMARQUE: si vous modifiez la période et la date-heure de début, vous pouvez obtenir tout intervalle dont vous avez besoin, comme des semaines à partir d'un jour donné, ou tout ce dont vous avez besoin
Si vous souhaitez générer des données de test pour cette requête, utilisez ceci:
CREATE TABLE Test
( Id INT IDENTITY PRIMARY KEY,
Time DATETIME,
Value FLOAT)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:00:22', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:03:22', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:04:45', 10)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:07:21', 20)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:10:25', 30)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:11:22', 30)
INSERT INTO Test(Time, Value) VALUES('2012-03-22T00:14:47', 30)
Le résultat de l'exécution de la requête est le suivant:
Period AvgValue
2012-03-22 00:00:00.000 10
2012-03-22 00:05:00.000 20
2012-03-22 00:10:00.000 30
En s'appuyant sur la réponse de @ JotaBe (sur laquelle je ne peux pas commenter - sinon je le ferais), vous pouvez également essayer quelque chose comme ça qui ne nécessiterait pas de sous-requête.
SELECT
AVG(value) AS 'AvgValue',
-- Add the rounded seconds back onto Epoch to get rounded time
DATEADD(
MINUTE,
(DATEDIFF(MINUTE, '1990-01-01T00:00:00', your_date) / 30) * 30,
'1990-01-01T00:00:00'
) AS 'TimeThirty'
FROM YourTable
-- WHERE your_date > some max lookback period
GROUP BY
(DATEDIFF(MINUTE, '1990-01-01T00:00:00', your_date) / 30)
Cette modification supprime les tables temporaires et les sous-requêtes. Il utilise la même logique de base pour le regroupement par intervalles de 30 minutes mais, lorsque je présente les données en retour dans le résultat, j'inverse simplement le calcul de l'intervalle pour obtenir la date et l'heure arrondies.
Donc, au cas où vous googlé cela, mais vous devez le faire dans mysql, ce qui était mon cas:
Dans MySQL, vous pouvez faire
GROUP BY
CONCAT(
DATE_FORMAT(`timestamp`,'%m-%d-%Y %H:'),
FLOOR(DATE_FORMAT(`timestamp`,'%i')/5)*5
)