Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to find missing hours and show data as 0

This query pulls counts for every hour of every day but leaves off any days and hours that don’t have counts. How can I fill in the missing dates and hours between the dates selected with 0 for the counts?

SELECT CAST(RecordTime AS date) AS Date, DATENAME(dw, RecordTime) AS [Day of the week], DATEPART(hour, RecordTime) AS [Hour of the day], COUNT(*) AS [Hourly Count]
    FROM Counts
    WHERE (RecordTime >= CONVERT(DATETIME, '2022-04-01 00:00:00', 102)) AND (RecordTime < CONVERT(DATETIME, '2022-05-01 00:00:00', 102)) AND (MachineNum = 11) AND (Cavity = 1)
    GROUP BY CAST(RecordTime AS date), DATEPART(hour, RecordTime), DATENAME(dw, RecordTime)
    ORDER BY Date, [Hour of the day]

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

As Larnu suggested, you need to generate a full dataset with all day+hour combinations in the range, in order to left join to. By my calculation you need 30 days * 24 hours = 720 rows. If you don’t already have a numbers table, or a calendar table, or a sequence generating function, you can generate this using recursive CTEs as follows:

DECLARE @StartDate     datetime = '20220401',
        @AfterLastDate datetime = '20220501';
        
;WITH days(d) AS
(
  SELECT 0 UNION ALL SELECT d+1 FROM days
  WHERE d < DATEDIFF(DAY, @StartDate, @AfterLastDate) - 1
), hours(h) AS
(
  SELECT 0 UNION ALL SELECT h+1 FROM hours WHERE h<23
),
dates(DayHour, h) AS
(
  SELECT DATEADD(HOUR, hours.h, DATEADD(DAY, days.d, @StartDate)), hours.h
  FROM days CROSS JOIN hours
)
SELECT d.DayHour, DATENAME(WEEKDAY, DayHour), d.h
  FROM dates AS d
  ORDER BY d.DayHour;

Output:

DayHour Day of the week Hour of the day
2022-04-01 00:00:00.000 Friday 0
2022-04-01 01:00:00.000 Friday 1
2022-04-01 02:00:00.000 Friday 2
… 714 more rows …
2022-04-30 21:00:00.000 Saturday 21
2022-04-30 22:00:00.000 Saturday 22
2022-04-30 23:00:00.000 Saturday 23

Now, we just need to left outer join that against your existing table:

DECLARE @StartDate     datetime = '20220401',
        @AfterLastDate datetime = '20220501';
        
;WITH days(d) AS
(
  SELECT 0 UNION ALL SELECT d+1 FROM days
  WHERE d < DATEDIFF(DAY, @StartDate, @AfterLastDate) - 1
), hours(h) AS
(
  SELECT 0 UNION ALL SELECT h+1 FROM hours WHERE h<23
),
dates(DayHour, h) AS
(
  SELECT DATEADD(HOUR, hours.h, DATEADD(DAY, days.d, @StartDate)), 
    hours.h FROM days CROSS JOIN hours
)
SELECT [Date] = CONVERT(date, d.DayHour), 
  [Day of the week] = DATENAME(WEEKDAY, d.DayHour), 
  [Hour of the day] = d.h,
  [Hourly Count] = COUNT(c.RecordTime)
FROM dates AS d
LEFT OUTER JOIN dbo.Counts AS c
ON c.RecordTime >= d.DayHour
  AND c.RecordTime < DATEADD(HOUR, 1, d.DayHour)
  AND c.MachineNum = 11
  AND c.Cavity = 1
GROUP BY CONVERT(date, d.DayHour), DATENAME(WEEKDAY, DayHour), d.h
ORDER BY [Date], [Hour of the day];
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading