One approach would be to generate a list of the time periods you want and then join your data table to that.
For example, if I want to group data by every 5 minutes, I can generate the "time slots" like this
declare @start datetime = (SELECT MIN(datum) from #demo);
declare @end datetime = (SELECT MAX(datum) from #demo);
declare @slotwidth int = 5;
WITH timeslots AS
(
SELECT @start AS startpoint, dateadd(MINUTE, @slotwidth, @start) as enddate
UNION ALL
SELECT dateadd(MINUTE, @slotwidth, startpoint), dateadd(MINUTE, @slotwidth, enddate) as enddate
FROM timeslots
WHERE dateadd(MINUTE, @slotwidth, enddate) <= @end
)
SELECT *
FROM timeslots t;
For my demo data in #demo this gives
startpoint enddate
2022-07-04 10:58:33.290 2022-07-04 11:03:33.290
2022-07-04 11:03:33.290 2022-07-04 11:08:33.290
2022-07-04 11:08:33.290 2022-07-04 11:13:33.290
2022-07-04 11:13:33.290 2022-07-04 11:18:33.290
2022-07-04 11:18:33.290 2022-07-04 11:23:33.290
I can then join those results to my original data, grouping by each timeslot e.g.
declare @start datetime = (SELECT MIN(datum) from #demo);
declare @end datetime = (SELECT MAX(datum) from #demo);
declare @slotwidth int = 5;
WITH timeslots AS
(
SELECT @start AS startpoint, dateadd(MINUTE, @slotwidth, @start) as enddate
UNION ALL
SELECT dateadd(MINUTE, @slotwidth, startpoint), dateadd(MINUTE, @slotwidth, enddate) as enddate
FROM timeslots
WHERE dateadd(MINUTE, @slotwidth, enddate) <= @end
)
SELECT t.startpoint, t.enddate, count(*)
FROM timeslots t
inner join #demo d on D.datum between T.startpoint AND T.enddate
group by t.startpoint, T.enddate;
which in my case gave me
startpoint enddate (No column name)
2022-07-04 10:58:33.290 2022-07-04 11:03:33.290 6
2022-07-04 11:03:33.290 2022-07-04 11:08:33.290 6
2022-07-04 11:08:33.290 2022-07-04 11:13:33.290 6
2022-07-04 11:13:33.290 2022-07-04 11:18:33.290 6
2022-07-04 11:18:33.290 2022-07-04 11:23:33.290 6
I generated some sample data with the following - basically just a number every minute from when I started...
WITH q AS
(
SELECT GETDATE() AS datum, 1 as etc
UNION ALL
SELECT dateadd(MINUTE, 1, datum), etc + 1
FROM q
WHERE dateadd(MINUTE, 1, datum) < dateadd(MINUTE, 30, getdate())
)
SELECT DATUM, etc
into #demo
FROM q;
Edit: If you want to include seconds in these slots then make
SECOND
your datepart and just amend variable
@slotwidth
to always represent your desired slot width in seconds