Porque você não está selecionando o item pelo qual está agrupando. Se você disse:
GROUP BY c.printable_name
Você obteria o NULL esperado. No entanto, você está agrupando por uma coluna diferente para que o MySQL não saiba que printable_name está participando de um grupo de rollup e seleciona qualquer valor antigo dessa coluna, na junção de all registros. (Portanto, é possível que você veja outros países além do Uzbequistão.)
Isso é parte de um problema mais amplo com o MySQL sendo permissivo sobre o que você pode SELECT em uma consulta GROUP BY. Por exemplo, você pode dizer:
SELECT gender FROM registrations GROUP BY country;
e o MySQL escolherá com prazer um dos valores de gênero para um registro de cada país, mesmo que não haja um vínculo causal direto (também conhecido como “dependência funcional”) entre país e gênero. Outros SGBDs recusarão o comando acima alegando que não há garantia de um gênero por país.(*)
Agora isso:
SELECT c.printable_name AS 'Country', count(*) AS '#'
FROM registrations r
INNER JOIN country c ON r.country = c.country_id
GROUP BY country
está OK, porque há uma dependência funcional entre r.country e c.printable_name (assumindo que você descreveu corretamente seu country_id como uma CHAVE PRIMÁRIA).
No entanto, a extensão WITH ROLLUP do MySQL é um pouco hack na maneira como funciona. No estágio de linha de rollup no final, ele percorre todo o conjunto de resultados de pré-agrupamento para obter seus valores e depois define a coluna group-by como NULL. Ele também não anula outras colunas que tenham uma dependência funcional nessa coluna. Provavelmente deveria, mas o MySQL atualmente não entende tudo sobre dependências funcionais.
Portanto, se você selecionar c.printable_name, ele mostrará o valor do nome do país escolhido aleatoriamente, e se você selecionar c.country_id, ele mostrará o ID do país escolhido aleatoriamente — mesmo que c.country_id seja o critério de junção, então deve ser o mesmo que r.country, que é NULL!
O que você pode fazer para contornar o problema é:
- grupo por printable_name em vez disso; deve estar OK se printable_names for único, ou
- selecione "r.country" e printable_name e verifique se é NULL ou
- esqueça WITH ROLLUP e faça uma consulta separada para a soma final. Isso será um pouco mais lento, mas também será compatível com ANSI SQL-92 para que seu aplicativo possa funcionar em outros bancos de dados.
(*:MySQL tem uma opção SQL_MODE ONLY_FULL_GROUP_BY que deveria resolver esse problema, mas vai longe demais e só permite selecionar colunas do GROUP BY, não colunas que têm uma dependência funcional do GROUP BY. Portanto, também fará com que as consultas válidas falhem, tornando-as geralmente inúteis.)