Но почему я получаю Узбекистан на общую сумму ??
Потому что вы НЕ ВЫБРАТЬ элемент, который вы GROUPING BY. Если вы сказали:
GROUP BY c.printable_name
Вы получите ожидаемый NULL. Однако вы группируете другой столбец, поэтому MySQL не знает, что имя_таблицы принимает участие в группе rollup, и выбирает любое старое значение из этого столбца, в объединении все регистрации. (Таким образом, вы можете увидеть другие страны, кроме Узбекистана.)
Это часть более широкой проблемы с тем, что 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 как ПЕРВИЧНЫЙ КЛЮЧ).
Однако расширение MySQL WITH ROLLUP является чем-то вроде взлома в способе его работы. На этапе свертки в конце он запускается по всему набору результатов предварительной группировки, чтобы захватить его значения, а затем устанавливает столбец «по группам» в NULL. Он также не содержит нулевые столбцы, которые имеют функциональную зависимость от этого столбца. Это, вероятно, должно, но MySQL в настоящее время не совсем понимает всю суть функциональных зависимостей.
Так что, если вы выберете c.printable_name, он покажет вам, какое значение имени страны выбрано в случайном порядке, и если вы выберете c.country_id покажет вам, какой из идентификаторов страны он выбрал случайно - хотя c.country_id является критерием соединения, поэтому он должен быть таким же, как r.country, что равно NULL!
Что вы можете сделать, чтобы работать вокруг проблемы:
- группа по printable_name вместо; должно быть ОК, если имена для печати уникальны, или
- выберите «r.country», а также имя для печати, и убедитесь, что для NULL или
- забудьте WITH ROLLUP и выполните отдельный запрос для конечной суммы. Это будет немного медленнее, но также будет совместимым с ANSI SQL-92, чтобы ваше приложение могло работать с другими базами данных.
(*: MySQL имеет возможность ONLY_FULL_GROUP_BY sql_mode, который должен решить эту проблему, но она идет слишком далеко и только позволяет выбрать столбцы из GROUP BY, а не столбцы, которые имеют функциональную зависимость от GROUP BY. так что он будет делать действительные запросы не так хорошо, что делает его вообще бесполезно.)
Насколько уверены, что проблема заключается не в том, как отображаются результаты? –
это происходит как в моем коде, так и в phpmyadmin. хотел бы попробовать протестировать его с помощью обычного браузера запросов mysql или чего-то еще, но у вас нет доступа. – Svish
Я просто играл с Rollup тоже. Я думаю, проблема здесь в том, что вы присоединяетесь к идентификатору страны к имени страны, поэтому все значения NULL не делают этого соединения и по какой-то причине сохраняют последнее значение имени вместо того, чтобы не иметь имени. – sphism