• Ok, next step is to join your data table to this hourly breakdown table. Try first with a full outer join as shown, this helps pinpoint any issues with aligning your data table with the buckets:
    ;WITH Headers AS (
     SELECT *
     FROM MST_SESSION_TEST p
     CROSS APPLY (
      SELECT TOP(1+DATEDIFF(HOUR,SES_START,SES_END))
       HourStart = DATEADD(HOUR,n,m.SessionStart),
       HourEnd = DATEADD(HOUR,n+1,m.SessionStart)
      FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) d (n)
      CROSS APPLY (SELECT SessionStart = DATEADD(MINUTE,DATEDIFF(MINUTE,'20000101',SES_START),'20000101')) m
     ) x
    )
    SELECT h.*, c.REC_ID, c.SES_NOTE, c.REC_DATETIME, c.REC_PRODUCT, c.REC_TOTAL
    FROM Headers h
    FULL OUTER JOIN MST_REC_TEST c
     ON c.SES_NOTE = h.SES_NOTE
     AND c.REC_DATETIME >= HourStart 
     AND c.REC_DATETIME < HourEnd

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden