Following will group by on hours basis, also i have created a virtual table that returns all hours so that we may right join and query will return groups with count zero as well.
Plus you may get groups of specified intervals by changing @TimeInterval, and complete format of that period is also provided.
DECLARE @TimeInterval int
set @TimeInterval = 4
SELECT h.hours/@TimeInterval as TimePeriod,
right('00'+convert(varchar,(h.hours/@TimeInterval)*@TimeInterval),2)
+'-'+
right('00'+convert(varchar,((h.hours/@TimeInterval)*@TimeInterval)+@TimeInterval-1),2) AS hours,
count(t.transactionid)
from transactiondetails t right join
(SELECT 0 AS hours
UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8
UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12
UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16
UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20
UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23) h
on datepart(hh,transactiondate) = h.hours
group by h.hours/@TimeInterval,
right('00'+convert(varchar,(h.hours/@TimeInterval)*@TimeInterval),2)
+'-'+
right('00'+convert(varchar,((h.hours/@TimeInterval)*@TimeInterval)+@TimeInterval-1),2)
order by h.hours/@TimeInterval
OUTPUT
For 4 hours IntervalTimePeriod hours [column]
0 00-03 17
1 04-07 3
2 08-11 42
3 12-15 30
4 16-19 46
5 20-23 2
For 2 hours Interval
TimePeriod hours [column]
0 00-01 13
1 02-03 4
2 04-05 3
3 06-07 0
4 08-09 5
5 10-11 37
6 12-13 12
7 14-15 18
8 16-17 31
9 18-19 15
10 20-21 0
11 22-23 2