The having keyword in SQL is used to filter aggregates. A SQL statement like select count(*) from table where count(*) > 8 group by column; is invalid. The where clause can only be used to filter rows.
Example:
grades table that records students fullnames and grades for different subjects.postgres@localhost:postgres> \d grades
+----------+-------------------+------------------------------------------------------+
| Column | Type | Modifiers |
|----------+-------------------+------------------------------------------------------|
| id | integer | not null default nextval('grades_id_seq'::regclass) |
| fullname | character varying | |
| grade | smallint | |
| subject | character varying | |
+----------+-------------------+------------------------------------------------------+
Indexes:
"grades_pkey" PRIMARY KEY, btree (id)
Time: 0.011s
postgres@localhost:postgres> select * from grades;
+----+--------------+-------+------------+
| id | fullname | grade | subject |
|----+--------------+-------+------------|
| 1 | John Doe | 6 | Math |
| 2 | Jane Doe | 3 | Math |
| 3 | John Jones | 7 | Math |
| 4 | Kate Doe | 3 | Math |
| 5 | Tom Jones | 9 | Literature |
| 6 | Kate Strong | 8 | Literature |
| 7 | Hans Black | 9 | Literature |
| 8 | Jack Strong | 7 | Literature |
| 9 | Jack Black | 9 | Biology |
| 10 | Lilly Strong | 9 | Biology |
+----+--------------+-------+------------+
SELECT 10
Time: 0.004s
postgres@localhost:postgres> select subject, avg(grade) from grades group by subject having avg(grade) >= 5;
+------------+--------------------+
| subject | avg |
|------------+--------------------|
| Literature | 8.2500000000000000 |
| Biology | 9.0000000000000000 |
+------------+--------------------+
SELECT 2
Time: 0.002s
postgres@localhost:postgres> select subject, count(*) from grades group by subject having count(*) > 3;
+------------+-------+
| subject | count |
|------------+-------|
| Math | 4 |
| Literature | 4 |
+------------+-------+
SELECT 2
Time: 0.004s