Skip to content
Advertisement

Using Over() with aggregate functions while calculating percentage

I am writing a query to print Total Students in each department in a college, I also want to print the percentage of those students in each department out of Total students in the college.

select dep.[Id] as DepId, dep.[Name] as Department, COUNT(s.[Id]) as [TotalStudents]
    , COUNT(S.[Id]) * 100/NULLIF(COUNT(COUNT(S.[Id]) OVER(), 0) AS [Percentage]
from dbo.[Department] dep
left join dbo.[student] s on dep.[Id] = s.[DepartmentId]
group by dep.[Id], dep.[Name]

Having issues with calculating percentage, the above query throwing an error

dbo.Student.Id is invalid in the select list because it is not contained in either an aggregate function.

If there are Total 10 students across all Departments and Dep1 has 5 students then the percentage should be 50.

Advertisement

Answer

You can use window functions like that, but you would need a window SUM of the counts, not a window COUNT(). I would also recommend putting a decimal value in the computation, to avoid integer division:

select d.[Id] as DepId, d.[Name] as Department, 
    count(s.[Id]) as [TotalStudents], 
    count(s.[Id]) * 100.0 / nullif(sum(count(s.[Id])) over(), 0) AS [Percentage]
from dbo.[Department] d
left join dbo.[student] s on d.[Id] = s.[DepartmentId]
group by d.[Id], d.[Name]
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement