Aber warum ich Usbekistan für die Gesamt bekommen ??
Da Sie das Element, das Sie gruppieren, nicht auswählen. Wenn Sie sagten:
GROUP BY c.printable_name
Sie würden die erwartete NULL erhalten. Sie gruppieren jedoch nach einer anderen Spalte, so dass MySQL nicht weiß, dass printable_name an einer Rollup-Gruppe teilnimmt, und wählt einen alten Wert aus dieser Spalte in der Verknüpfung alle Registrierungen aus. (So ist es möglich, dass Sie andere Länder als Usbekistan sehen werden.)
Dies ist Teil eines größeren Problems mit MySQL, das erlaubt, was Sie in einer GROUP BY-Abfrage auswählen können. Zum Beispiel können Sie sagen:
SELECT gender FROM registrations GROUP BY country;
und MySQL wird gerne von jedem Land eine der Geschlechter Werte für eine Registrierung auswählen, auch wenn es kein direkter Kausalzusammenhang (auch bekannt als „funktionale Abhängigkeit“) zwischen Land und Geschlecht . Andere DBMS werden den obigen Befehl auf dem Gelände verweigern, dass es nicht ein Geschlecht ist garantiert pro Land sein (*)
Nun, dies:.
SELECT c.printable_name AS 'Country', count(*) AS '#'
FROM registrations r
INNER JOIN country c ON r.country = c.country_id
GROUP BY country
in Ordnung ist, weil es eine funktionale Abhängigkeit ist zwischen r.country und c.printable_name (vorausgesetzt, Sie haben Ihre country_id korrekt als PRIMARY KEY beschrieben).
Allerdings ist die WITH ROLLUP-Erweiterung von MySQL ein bisschen ein Hack in der Art, wie es funktioniert. In der Rollup-Row-Phase am Ende wird sie über die gesamte Vorgruppierungs-Ergebnismenge ausgeführt, um ihre Werte zu erfassen, und dann setzt die Group-by-Spalte auf NULL. Es werden auch keine anderen Spalten gelöscht, die eine funktionale Abhängigkeit von dieser Spalte haben. Wahrscheinlich sollte es, aber MySQL versteht derzeit nicht das ganze über funktionale Abhängigkeiten.
Wenn Sie also c.printable_name auswählen, wird Ihnen angezeigt, welcher Landnamenswert zufällig ausgewählt wurde, und wenn Sie c auswählen.country_id zeigt Ihnen die Länder-ID an, die zufällig ausgewählt wurde - obwohl c.country_id das Join-Kriterium ist, muss also dasselbe sein wie r.country, was NULL ist!
Was können Sie tun, um das Problem zu umgehen ist:
- Gruppe von printable_name statt; sollte in Ordnung sein, wenn printable_names einzigartig sind, oder
- „r.country“ sowie printable_name wählen, und dass für seine NULL überprüfen oder
- WITH ROLLUP und macht eine separate Abfrage für die Endsumme vergessen. Dies wird etwas langsamer sein, aber es wird auch ANSI SQL-92-konform sein, damit Ihre App in anderen Datenbanken funktionieren kann.
(*: MySQL hat eine SQL_MODE Option ONLY_FULL_GROUP_BY, die dieses Problem adressieren soll, aber es geht viel zu weit und nur können Sie Spalten aus der GROUP BY wählen, keine Spalten, die eine funktionelle Abhängigkeit von der GROUP haben BY. so wird es auch machen scheitern gültige Abfragen, es in der Regel nutzlos.)
Wie sicher sind Sie, dass das Problem nicht ist, wie die Ergebnisse angezeigt werden? –
es passiert sowohl in meinem Code und in der phpmyadmin Sache. Ich wünschte, ich könnte versuchen, es mit regulären MySQL Abfrage-Browser oder etwas zu testen, aber keinen Zugriff haben. – Svish
Ich spielte auch nur mit Rollup. Ich denke, das Problem hier ist, dass Sie der Länder-ID den Namen des Landes beitreten, so dass alle NULL-Werte diesen Join nicht tun, und aus irgendeinem Grund den letzten Wert des Namens behalten, anstatt keinen Namen zu haben. – sphism