1) WHERE clause is processed right after FROM clause in the logical order of query processing, which means it is processed before GROUP BY clause while HAVING clause is executed after groups are created.
2) If used in GROUP BY, You can refer any column from a table in WHERE clause but you can only use columns which are not grouped or aggregated.
3) Since WHERE clause is evaluated before groups are formed, it evaluates for per row. On the other hand, the HAVING clause is evaluated after groups are formed hence it evaluates for per group. You can further see the Introduction to SQL course on Pluralsight to learn more about.