Search code examples
sqlsql-serveraverageaggregate-functionshaving-clause

SQL Server - Exclude records from query result set based on condition


Using the below query i am trying to get Average number of FTE Students in each department, Total Students in each department divided by Total FTE students in that department.

In few departments there will be no FTE students and for that i used case statement to consider average as 0 in that case there are no FTE students (CASE U.[IsFTEStudent] WHEN 1 THEN 1 END)=0 THEN 0

SELECT D.[DepartmentId],
    CASE WHEN COUNT(CASE U.[IsFTEStudent] WHEN 1 THEN 1 END)=0 THEN 0
    ELSE COUNT(S.[StudentId])/COUNT(CASE U.[IsFTEStudent] WHEN 1 THEN 1 END) END AS 'AverageOfFTEStudents'
    FROM dbo.[Student] S
    INNER JOIN [dbo].User U
    ON S.[StudentId] = U.[UserId]
    INNER JOIN dbo.[Department] D
    ON D.DepartmentId = S.[DepartmentId]
    WHERE D.CollegeId = 5
    GROUP BY S.DepartmentId

The above query gives result even with average 0, now i want to exclude those departments who have average of 0 FTE Students, which means there are no FTE students.

In short the departments which have 'AverageOfFTEStudents' as 0 should be excluded from my result


Solution

  • I think you want a having clause; and you can simplify the computation logic with AVG():

    SELECT S.[DepartmentId],
        AVG(CASE WHEN [IsFTEStudent] = 1 THEN 1.0 ELSE 0 END) AS [AverageOfFTEStudents]
    FROM dbo.[Student] S
    INNER JOIN [dbo].User U ON ON S.[StudentId] = U.[UserId]
    INNER JOIN dbo.[Department] D ON D.DepartmentId = S.[DepartmentId]
    WHERE D.CollegeId = 5
    GROUP BY S.DepartmentId
    HAVING SUM(CASE WHEN [IsFTEStudent] = 1 THEN 1 ELSE 0 END) > 0
    

    Depending on the actual datatype and values of IsFTEStudent, we might be able to simplify the aggregate expressions a little. If it's an integer with 0/1 values for example, then:

    SELECT S.[DepartmentId],
        AVG([IsFTEStudent] * 1.0) AS [AverageOfFTEStudents]
    FROM dbo.[Student] S
    INNER JOIN [dbo].User U ON ON S.[StudentId] = U.[UserId]
    INNER JOIN dbo.[Department] D ON D.DepartmentId = S.[DepartmentId]
    WHERE D.CollegeId = 5
    GROUP BY S.DepartmentId
    HAVING SUM([IsFTEStudent]) > 0