Q:

PostgreSQL: print names of people who are students and the count of students from postgrad are more than undergrad for that course

I'm trying to write a PostgreSQL and have gone horribly wrong. 
I need to print names of people who are students and the count of students from postgrad are more than undergrad for that course
select p.name from Person p join Course c on (p.course=c.id) join Student s on (c.st_info=s.id) group by p.code,p.name having count(s.type='undergrad') > count(s.type='postgrad');

A:

You would identify the courses using logic such as this:
select c.id
from Course c join
     Student s
     on c.st_info = s.id
group by c.id
having sum( (s.type = 'postgrad')::int ) > sum( (s.type = 'undergrad')::int );

I'll let you figure out how to get the students who are actually in the courses. 
Notes:

Your logic in the having was reversed.   That is a pretty basic error. 
count() counts the number of non-NULL values.   The boolean expressions are probably always non-NULL, so they will return the same values.   sum() is what you want. 
Your data model doesn't really make sense.   Why does course have a student id?   Why does person have a course id?