WHERE runs on individual rows before GROUP BY; HAVING runs on the grouped result and may use aggregates. The distinction has nothing to do with data types or joins, and the order in the last option is reversed — WHERE first, HAVING later.
Official docs