If you have a calendar table, then this becomes a pretty basic query:
SELECT b.Employee,
c.Date,
Call_count = ISNULL(a.Call_count, 0)
FROM dbo.Calendar AS c
CROSS JOIN dbo.TableB AS b
LEFT JOIN dbo.TableA AS a
ON a.Date = c.[Date]
AND a.Employee = b.Employee
WHERE c.Date >= DATEADD(DAY, -30, CAST(GETDATE() AS DATE))
AND c.Date < GETDATE();
The key being you first generate a full set of all cominations of dates and names, then LEFT JOIN to your data, so now you are not limited to results that exist in TableA.
If you don't have a calendar table, then you can generate a list of dates on the fly. Much more reading about this is here:
Part 3 is specifically relevant as it deals with dates.
But for simplicity to get a list of the last 30 days you can generate a list of number from 1-30 using this:
SELECT Date = DATEADD(DAY, -ROW_NUMBER() OVER(ORDER BY n1.n), CONVERT(DATE, GETDATE()))
FROM (VALUES (1),(1),(1),(1),(1),(1)) n1 (n)
CROSS JOIN (VALUES (1),(1),(1),(1),(1)) n2 (n);
There are 3 steps here.
- Use table value constructors to create a set of 6 rows and a set of 6 rows, and cross join them to get 30 rows.
- Use
ROW_NUMBER() to create a sequential id for each row.
- Subtract this number from today's date to get a list of the last 30 days.
You can now substitute this set into the query above in place of the calenar table:
WITH Calendar AS
( SELECT Date = DATEADD(DAY, -ROW_NUMBER() OVER(ORDER BY n1.n), CONVERT(DATE, GETDATE()))
FROM (VALUES (1),(1),(1),(1),(1),(1)) n1 (n)
CROSS JOIN (VALUES (1),(1),(1),(1),(1)) n2 (n)
)
SELECT b.Employee,
c.Date,
Call_count = ISNULL(a.Call_count, 0)
FROM Calendar AS c
CROSS JOIN dbo.TableB AS b
LEFT JOIN dbo.TableA AS a
ON a.Date = c.[Date]
AND a.Employee = b.Employee ;
insertinto table ?