Тъй като не избирате елемента, по който ГРУПИРАТЕ. Ако казахте:
GROUP BY c.printable_name
Ще получите очакваното NULL. Въпреки това вие групирате по друга колона, така че MySQL не знае, че printable_name участва в сборна група, и избира всяка стара стойност от тази колона, в обединяването на всички регистрации. (Така че е възможно да видите други страни освен Узбекистан.)
Това е част от по-широк проблем с MySQL, който разрешава какво можете да ИЗБЕРЕТЕ в заявка GROUP BY. Например, можете да кажете:
SELECT gender FROM registrations GROUP BY country;
и MySQL с радост ще избере една от стойностите за пол за регистрация от всяка държава, въпреки че няма пряка причинно-следствена връзка (известна още като „функционална зависимост“) между държава и пол. Други СУБД ще откажат горната команда на основание, че не е гарантирано, че има един пол на държава.(*)
Сега, това:
SELECT c.printable_name AS 'Country', count(*) AS '#'
FROM registrations r
INNER JOIN country c ON r.country = c.country_id
GROUP BY country
е ОК, защото има функционална зависимост между r.country и c.printable_name (ако приемем, че сте описали правилно своя country_id като ПРАВИЛЕН КЛЮЧ).
Въпреки това разширението WITH ROLLUP на MySQL е малко хак в начина, по който работи. На етапа на сборния ред в края той преминава през целия набор от резултати за предварително групиране, за да вземе стойностите му, и след това задава колоната група по NULL. Не нулира и други колони, които имат функционална зависимост от тази колона. Вероятно би трябвало, но MySQL в момента наистина не разбира цялата работа за функционалните зависимости.
Така че, ако изберете c.printable_name, той ще ви покаже коя стойност на името на държавата е избрана произволно, а ако изберете c.country_id, ще ви покаже коя държава е избрал произволно — въпреки че c.country_id е критерият за присъединяване, така трябва да бъде същото като r.country, което е NULL!
Това, което можете да направите, за да заобиколите проблема е:
- вместо това групирайте по име за печат; трябва да е наред, ако printable_names са уникални, или
- изберете „r.country“, както и printable_name и проверете дали е NULL, или
- забравете WITH ROLLUP и направете отделна заявка за крайната сума. Това ще бъде малко по-бавно, но също така ще бъде съвместимо с ANSI SQL-92, така че приложението ви да може да работи с други бази данни.
(*:MySQL има опция SQL_MODE ONLY_FULL_GROUP_BY което би трябвало да реши този проблем, но отива твърде далеч и ви позволява да избирате само колони от GROUP BY, а не колони, които имат функционална зависимост от GROUP BY. Така че валидните заявки също ще се провалят, което го прави като цяло безполезно.)