We are building a query to count the number of events per hour, per day. Most days there are hours that do not have any activity and therefore where the query is run the cou
You are going to somehow need a table of days and hours, and then you will have to do an outer join between that table and your query. Here's how I would do it. Note that this solution will only work in SQL Server 2005 and 2008. If you don't have those platforms, you'll have to actually create a table of times in your database from which you can join off of:
DECLARE @MinDate DATETIME;
SET @MinDate = CONVERT(varchar, GETDATE(), 101);
WITH times AS (
SELECT @MinDate as dt, 1 as depth
UNION ALL
SELECT DATEADD(hh, depth, @MinDate), 1 + depth as depth
FROM times
WHERE DATEADD(hh, depth, @MinDate) <= GETDATE())
SELECT DATEPART(YEAR, t.dt) as [Year],
DATEPART(MONTH, t.dt) as [Month],
DATEPART(DAY, t.dt) as [Day],
DATEPART(HOUR, t.dt) as [Hour],
COUNT(tdm_msg) as Total_ACTIVITES
FROM times t
LEFT JOIN (SELECT * FROM TCKT_ACT WHERE tdm_msg = '4162' and dev_time >= @MinDate) a
ON DATEPART(HOUR, t.dt) = DATEPART(HOUR, a.dev_time)
AND MONTH(t.dt) = MONTH(a.dev_time)
AND DAY(t.dt) = DAY(a.dev_time)
AND YEAR(t.dt) = YEAR(a.dev_time)
GROUP BY DATEPART(YEAR, t.dt) ,
DATEPART(MONTH, t.dt) ,
DATEPART(DAY, t.dt),
DATEPART(HOUR, t.dt)
ORDER BY DATEPART(YEAR, t.dt) asc,
DATEPART(MONTH, t.dt) asc,
DATEPART(DAY, t.dt) asc,
DATEPART(HOUR, t.dt) asc
OPTION (MAXRECURSION 0); /* Just in case you want a longer timespan later on... */
Note that the WITH statement at the top is called a recursive common table expression, and is a good way of generating sequential tables with relatively small numbers of elements, like you have here.