Давайте возьмем генератор строк, который генерирует даты каждый диапазонSize от startDate:
DECLARE @rangeSize INT = 5;
DECLARE @startDate DATETIME = '2020-01-01 00:00';
WITH RG(D,D2) AS (
SELECT @startDate AS D, DATEADD(MINUTE, @rangeSize, @startDate) AS D2
UNION ALL
SELECT DATEADD(MINUTE, @rangeSize, D), DATEADD(MINUTE, @rangeSize, D2)
FROM RG a
WHERE D < DATEADD(MINUTE, @rangeSize * 100, @startDate)
)
SELECT D,D2
FROM RG
OPTION (MAXRECURSION 100);
Теперь давайте подключим его к вашим данным и посчитаем данные:
DECLARE @rangeSize INT = 5;
DECLARE @startDate DATETIME = '2020-01-01 00:00';
WITH RG(D,D2) AS (
SELECT @startDate AS D, DATEADD(MINUTE, @rangeSize, @startDate) AS D2
UNION ALL
SELECT DATEADD(MINUTE, @rangeSize, D), DATEADD(MINUTE, @rangeSize, D2)
FROM RG a
WHERE D < DATEADD(MINUTE, @rangeSize * 100, @startDate)
)
SELECT r.D as StartDate, r.D2 as EndDate, COUNT(m.ID) as Count as EndDate
FROM
RG r
LEFT JOIN
my_table m ON m.dateval > r.D AND m.dateval <= r.D2
GROUP BY r.D, r.D2
OPTION (MAXRECURSION 100);
Примечание Я использовал >
и <=
для диапазона, потому что вы, кажется, классифицируете диапазон, например, с 15:01 до 20:00, тогда как для меня более естественно иметь 15:00 до 19:59 как "принадлежащий диапазон 15-20 "