This query will return the pivot table in more or less the desired form:
WITH t(d, h, n) AS (
SELECT CAST(t AS DATE) AS d, h, COUNT(CASE WHEN h = datepart(hh, t) THEN 1 END) AS n
FROM (
VALUES
('2017-01-02 05:27:10.117', 'Sam'),
('2017-01-02 15:27:10.117', 'Sam'),
('2017-01-03 06:27:10.116', 'Ben'),
('2017-01-03 06:28:10.119', 'Aam')
) AS t(t, s)
CROSS JOIN (
VALUES (0) , (1) , (2) , (3) , (4) , (5),
(6) , (7) , (8) , (9) , (10), (11),
(12), (13), (14), (15), (16), (17),
(18), (19), (20), (21), (22), (23)
) AS h(h)
GROUP BY CAST(t AS DATE), h
)
SELECT *
FROM t
PIVOT (
sum(n) FOR h IN (
[0] , [1] , [2] , [3] , [4] , [5],
[6] , [7] , [8] , [9] , [10], [11],
[12], [13], [14], [15], [16], [17],
[18], [19], [20], [21], [22], [23]
)
) t
ORDER BY d
Explanation:
- The
CROSS JOIN operation combines each timestamp (t) with each hour (h) in a day (hardcoded here) by forming a cartesian product. I've recently blogged about the utility of CROSS JOIN in this article here.
- The
COUNT() aggregate function the counts the number of rows (n) (timestamps) that match an actual hour.
- Finally,
PIVOT transposes the h column into individual columns