--- Get the min admit and max discharge date within the data set
DECLARE @MinDate DATE,
@MaxDate DATE
SELECT @MinDate = DATEADD(day, -1, min(date)) from table_of_interest
SELECT @MaxDate = DATEADD(day ,1, max(date)) from table_of_interest
/*
The second-inner-most subquery on tableA grabs min and max dates per group.
Then cross join with b produces all possible dates within the min-max range per group.
And finally outer select uses outer join with TableA and fills value column with 0 for dates that are missing in TableA.
*/
SELECT p.date, COALESCE(a.value, 0) value, p.grp_no
FROM
( -- outer join and fill value column with 0 for dates that are missing in TableA.
SELECT grp_no, date
FROM
( -- get the start and end date for each grp_no
SELECT grp_no, MIN(date) min_date, MAX(date) max_date
FROM tableA
GROUP BY grp_no
) q CROSS JOIN ( -- cross join produces all possible dates within the min-max range per group
-- subquery to generate all dates between the two dates
SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b;
) b
WHERE b.date BETWEEN q.min_date AND q.max_date
) p LEFT JOIN TableA a
ON p.grp_no = a.grp_no
AND p.date = a.date