SQL: Fill completely missing observations

I found a different solution for the missing days problem I mentioned yesterday. By combining the advice of two stackoverflow posts (here and here), I was able to fill in the missing rows between a start and end date for every subject.

Here’s what the generic version of my solution looks like:

--- 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
Previous
Previous

Multiple Comparison Correction

Next
Next

Differencing with SQL LAG()