I have a calendar table (c) with a set of 3 month dates:
2021-06-01 2021-07-01 2021-08-01
I have a Stats table (s) with views of each product on the website.
Prod1 | 2021-06-01 Prod1 | 2021-06-01 Prod1 | 2021-08-01 Prod2 | 2021-07-01 Prod2 | 2021-08-01 Prod2 | 2021-08-01
I need to count the views per product per month whether there are views or not.
I have followed many SO answers (SQL – Group By with Left Join) and I cannot see a problem with the code below.
DECLARE @Start date SET @Start=DATEADD(month, DATEDIFF(month, 0,DATEADD(month, -3, getdate())), 0) SELECT s.ProductID, c.themonth, ISNULL(Count(s.ProductID),0) As Total_Views FROM #calendar c LEFT JOIN ( SELECT ProductID,FirstDayOfMonth FROM Stats WHERE FirstDayofMonth >= @Start ) s ON c.themonth = s.FirstDayOfMonth GROUP BY c.themonth,s.ProductID ORDER BY s.ProductID,c.themonth
I get results only for ProductIDs that have views in a particular month, instead of a row for each ProductID and each Month whether there are views or not.
With the data above, the result I want is:
Prod1 | 2021-06-01 | 2 Prod1 | 2021-07-01 | 0 Prod1 | 2021-08-01 | 1 Prod2 | 2021-06-01 | 0 Prod2 | 2021-07-01 | 1 Prod2 | 2021-08-01 | 2
Advertisement
Answer
Use a cross join
to generate the rows and then a left join
to bring in the data:
select c.themonth, p.productid, count(s.productid) as sales_in_month from #calendar c cross join (select distinct productid from stats) p left join stats s on s.productid = p.productid and s.firstdayofmonth = c.themonth group by c.themonth, p.productid;