This has nothing to do with the case
statement. The issue is the scoping rules for correlated subqueries. They only nest one level deep. Here is another question with this problem.
For your example, you don't need nested subqueries. You can just do:
where (CASE when emp.department = 'C'
then (select count(*)
from tbl_emp_department ted
where ted.department = emp.department
)
when emp.department = 'C'
then (select count(*)
from tbl_emp_department ted
where ted.department = emp.department and ted.id = 7
)
END) > 0
However, because your query doesn't really make sense (the same conditions for the two when
clauses, I suspect that your actual query may be more complicated. You may have to find another approach to do what you want, using explicit joins and aggregations or using analytic functions.