Je suis très en retard à la fête, mais cela n'apparaît dans aucune des réponses existantes:
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', date_column) / 10 * 10, '2000')
- Les termes
10
et MINUTE
peuvent être modifiés en n'importe quel nombre et DATEPART
, respectivement.
- C'est une
DATETIME
valeur, ce qui signifie:
- Cela fonctionne bien sur de longs intervalles de temps. (Il n'y a pas de collision entre les années.)
- L'inclure dans l'
SELECT
instruction donnera à votre sortie une colonne avec une jolie sortie tronquée au niveau que vous spécifiez.
'2000'
est une "date d'ancrage" autour de laquelle SQL effectuera le calcul de la date. Jereonh a découvert ci - dessous que vous rencontrez un débordement d'entier avec l'ancre précédente ( 0
) lorsque vous regroupez les dates récentes par secondes ou millisecondes. †
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', aa.[date]) / 10 * 10, '2000')
AS [date_truncated],
COUNT(*) AS [records_in_interval],
AVG(aa.[value]) AS [average_value]
FROM [friib].[dbo].[archive_analog] AS aa
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', aa.[date]) / 10 * 10, '2000')
ORDER BY [date_truncated]
Si vos données couvrent des siècles, ‡ l' utilisation d'une seule date d'ancrage pour le regroupement en seconde ou en milliseconde rencontrera toujours le débordement. Si cela se produit, vous pouvez demander à chaque ligne d'ancrer la comparaison de regroupement à minuit de sa propre date:
Utilisez DATEADD(DAY, DATEDIFF(DAY, 0, aa.[date]), 0)
plutôt que '2000'
partout où il apparaît ci-dessus. Votre requête sera totalement illisible, mais cela fonctionnera.
Une alternative pourrait être CONVERT(DATETIME, CONVERT(DATE, aa.[date]))
le remplacement.
† 2 32 ≈ 4.29E + 9, donc si votre DATEPART
est - SECOND
, vous obtenez 4,3 milliards de secondes de chaque côté, ou « ancre ± 136 ans. » De même, 2 32 millisecondes équivaut à ≈ 49,7 jours.
‡ Si vos données couvrent réellement des siècles ou des millénaires et sont toujours exactes à la seconde ou à la milliseconde… félicitations! Quoi que vous fassiez, continuez à le faire.
ROUND((DATEPART(MINUTE, DT.[Date]) / 5),0,1) * 5
, de sorte que lorsque je regarde les données, elles sont corrélées avec le créneau horaire le plus proche