I want to query a database for users and the the amount of time they spent on each Activity Category. These categories are stored in the table ActivityCategory (int Id, varchar Name). There's only 8 of them and I want to see all of them, even when nobody spent time on a specific category.
I have the following query:
select u.NoEmploye, u.FirstName, u.LastName, Total=sum(h.NbHeures), ac.Name from Users u join Semaines s on u.EntityGuid=s.UserGuid join HeuresProjets hp on s.Id=hp.WeekId join Heures h on hp.HPId=h.HpGuid join ActivityCodes code on h.Code=code.ActivityId join ActivityCategory ac on code.Categorie=ac.Id group by u.NoEmploye, u.FirstName, u.LastName, ac.Name order by u.NoEmploye It works fine but it doesn't return unused ActivityCategories. I tried every combination of full/left/right/inner/outer/you-name-it joins. The best I could get is completely null rows when a category is used by nobody and a null ac.Name for categories a specific user doesn't use but others do. I suspect the group by [...]ac.Name part is what's "eating" the unused categories. What am I doing wrong? Should I write a select query the a second one to group the results? I'll have a dozen more similar queries to write so I'd like to understand instead of just having a fixed query with no explanation.
EDIT Lamak's second query works so far but it has the same problem when I add a where clause.
EDIT2 ypercube' edit works perfectly
Now let's see if I understand the query correctly. I coalesce the Sum with 0 to have a proprer value when the result would be null. I start the selection from ActivityCategory to make sure I have all of them, even the unused ones, which I cross join with users to have every combination of ActivityCategory and Users. I left join Activitycodes to only get relevant rows and then I inner join my other tables to get to Semaine. My condition are applied to the Semaine table's join because I want to filter my data before the cross join. Finally, I group my data by Users and ActivityCategory to have the sum works.