Incorrect result when using 'case when count()=0' & 'where'
just move where conditions to the join part:

select U.Mail, count(P.ID) as PostCount, 
  case 
    when count(P.ID) = 0 then 'none'
        when count(P.ID) &lt;= 2 then 'few'
        when count(P.ID) &lt;= 5 then 'medium'
    else 'many'
  end PostCountCategory
from Users U 
    left join Tagging T on U.Mail = T.Mail
    left join Post P on T.IDPost = P.ID AND datediff(day,P.DatePosted,getdate()) &lt;= 30
group by U.Mail, U.Gender


also your original condition doesn't alloow SQL Server to use index seek. It would be better to rewrite it this way:

P.DatePosted &gt;= dateadd(day, -30, cast(getdate() as date))