Tôi nghĩ bạn đang làm phức tạp quá mức.
Bạn có thể sử dụng GROUP BY (DATEDIFF (MINUTE, '2017-01-01', TheDateTime) / 30
để phân nhóm 30 phút một lần. Tất nhiên, ngày tôi đã chọn chỉ là một ngày ngẫu nhiên. Bạn có thể chọn, nếu bạn muốn, ngày đầu tiên (hoặc cuối cùng) trong dữ liệu mẫu của mình.
Và bạn cũng có thể sử dụng kỹ thuật này để lấy mọi khoảng thời gian của bất kỳ phần thời gian nào - chỉ cần thay đổi từ khóa MINUTE đến bất kỳ phần ngày nào bạn muốn sử dụng và
30
intreval đến bất kỳ khoảng thời gian nào bạn muốn.
Hãy xem xét dữ liệu mẫu sau:
;WITH CTE AS
(
SELECT CAST('2017-01-01T00:00:00' as datetime) As TheDateTime, 0 as rn
UNION ALL
SELECT DATEADD(MINUTE, 1, TheDateTime), rn + 1
FROM CTE
WHERE rn < 60
)
SELECT TheDateTime, rn INTO #T
FROM CTE
OPTION(MAXRECURSION 0)
#T
bây giờ chứa dữ liệu sau:
TheDateTime rn
2017-01-01 00:00:00.000 0
2017-01-01 00:01:00.000 1
2017-01-01 00:02:00.000 2
2017-01-01 00:03:00.000 3
...
2017-01-01 00:59:00.000 59
2017-01-01 01:00:00.000 60
Để có được rn tối đa được nhóm lại trong 30 phút, bạn chỉ cần điều này:
SELECT DATEDIFF(MINUTE, '2017-01-01', TheDateTime) / 30, MAX(rn)
FROM #T
GROUP BY DATEDIFF(MINUTE, '2017-01-01', TheDateTime) / 30
Kết quả:
interval max_rn
0 29
1 59
2 60