Acho que o problema é que HAVING é aplicado depois de GROUP BY, mas ainda antes da fase SELECT. Percebo que é confuso porque a cláusula HAVING faz referência a uma coluna da instrução SELECT, mas acho que basicamente executa o que estiver na instrução SELECT duas vezes - uma vez para ter e depois novamente para o SELECT.
Por exemplo, veja esta resposta .
Observe que é especialmente confuso porque se você se referir a um nome de coluna que não aparece na instrução SELECT em uma cláusula HAVING, ele gerará um erro.
Por exemplo, este violino
Mas de acordo com o violino acima, ele ainda permitirá que você filtre com base no resultado de uma função que não aparece na saída. Para encurtar a história, a cláusula HAVING ainda está fazendo o que você deseja, mas você não pode filtrar um valor aleatório e exibi-lo ao mesmo tempo usando essa abordagem. Se você precisar fazer isso, precisará usar uma subconsulta para corrigir o valor primeiro, para que a consulta externa possa filtrar e exibir nele.
Além disso, para deixar claro, provavelmente vale a pena usar RAND() na cláusula having, não na parte SQL. Embora eu entenda que esta pergunta está perguntando por que ele está fazendo isso em vez de tentar resolver o problema especificamente.