Partiye çok geç kaldım, ancak bu mevcut cevapların hiçbirinde görünmüyor:
GROUP BY DATEADD(MINUTE, DATEDIFF(MINUTE, '2000', date_column) / 10 * 10, '2000')
10
Ve MINUTE
terimleri herhangi bir sayı olarak değiştirildi ve edilebilmektedir DATEPART
sırasıyla.
- Bu bir
DATETIME
değerdir, yani:
- Uzun zaman aralıklarında iyi çalışır. (Yıllar arasında bir çarpışma yoktur.)
- İfadeye dahil edilmesi,
SELECT
çıktınıza, belirttiğiniz düzeyde kesilmiş güzel bir çıktı içeren bir sütun verecektir.
'2000'
SQL'in tarih matematiğini gerçekleştireceği bir "çapa tarihi" dir. Jereonh , son tarihleri saniye veya milisaniye göre grupladığınızda , önceki çapa ( ) ile tamsayı taşmasıyla karşılaştığınızı aşağıda keşfetti0
. †
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]
Verileriniz yüzyıllara yayılıyorsa, ‡ ikinci veya milisaniye gruplama için tek bir bağlantı tarihi kullanmak yine de taşma ile karşılaşacaktır. Bu durumda, her satırdan binning karşılaştırmasını kendi tarihinin gece yarısına sabitlemesini isteyebilirsiniz:
Yukarıda göründüğü yer DATEADD(DAY, DATEDIFF(DAY, 0, aa.[date]), 0)
yerine kullanın '2000'
. Sorgunuz tamamen okunamayacak, ancak işe yarayacak.
Bunun CONVERT(DATETIME, CONVERT(DATE, aa.[date]))
yerine bir alternatif de olabilir .
† 2 32 ≈ 4.29E + 9, bu nedenle eğer DATEPART
IS SECOND
, sen iki tarafında 4300000000 saniye olsun, ya da "çapa ± 136 yıl." Benzer şekilde, 2 32 milisaniye ≈ 49.7 gündür.
‡ Eğer gerçekte açıklıklı yüzyıllar veya bin sene öncesine ve bir veri hala saniye veya milisaniye ... tebrikler doğru! Ne yaparsan yap, yapmaya devam et.
ROUND((DATEPART(MINUTE, DT.[Date]) / 5),0,1) * 5
, böylece verilere baktığımda en yakın zaman