web-dev-qa-db-de.com

MySQL: ist nicht in GROUP BY enthalten

Die Site liefert Ergebnisse, aber mit SELECT COUNT und SELECT-Abfrage, wobei GROUP BY zwei unterschiedliche Ergebniszahlen hat. Dies ist wahrscheinlich auf den Fehler zurückzuführen, der in phpmyadmin, aber nicht auf der Site angezeigt wird.

Die Abfragen:

SELECT count(DISTINCT `name`) as `numrows` FROM `users` WHERE `verified` = '1'

SELECT `name`, `type`, `language`, `code` FROM `users` WHERE `verified` = '1' GROUP BY `name` ORDER BY `count` DESC LIMIT 0, 25

PhpMyAdmin liefert den folgenden Fehler:

1055 - 'main.users.type' ist nicht in GROUP BY enthalten

Beim Lesen von MySQL-Dokumenten ist mir immer noch unklar, was ich reparieren muss. Ich kann das nicht verstehen.

18
James Cordeiro

Sie müssen eine vollständige Gruppe haben durch:

SELECT `name`, `type`, `language`, `code` 
FROM `users` 
WHERE `verified` = '1' 
GROUP BY `name`, `type`, `language`, `code` 
ORDER BY `count` DESC LIMIT 0, 25

SQL92 erfordert, dass alle Spalten (mit Ausnahme der Aggregate) in der select-Klausel Teil der group by-Klausel sind. SQL99 löst diese Einschränkung ein wenig und gibt an, dass alle Spalten in der select-Klausel funktional von der group by-Klausel abhängig sein müssen. MySQL erlaubt standardmäßig eine teilweise Gruppierung nach und dies kann zu nicht deterministischen Antworten führen. Beispiel:

create table t (x int, y int);
insert into t (x,y) values (1,1),(1,2),(1,3);
select x,y from t group by x;
+------+------+
| x    | y    |
+------+------+
|    1 |    1 |
+------+------+

Das heißt ein zufälliges y wird für die Gruppe x ausgewählt. Man kann dieses Verhalten verhindern, indem man @@ sql_mode setzt:

set @@sql_mode='ONLY_FULL_GROUP_BY';
select x,y from t group by x; 
ERROR 1055 (42000): 'test.t.y' isn't in GROUP BY
29
Lennart

Die beste Lösung für dieses Problem ist natürlich die Verwendung eines vollständigen GROUP BY-Ausdrucks.

Es gibt jedoch eine andere Lösung, die die ONLY_FULL_GROUP_BY-Blockierung der alten MySQL-Erweiterung auf GROUP BY verhindert.

SELECT name, 
       ANY_VALUE(type) type,
       ANY_VALUE(language) language,
       ANY_VALUE(code) code 
  FROM users  
 WHERE verified = '1' 
 GROUP BY name 
 ORDER BY count DESC LIMIT 0, 25

ANY_VALUE() erklärt explizit, was in den unvollständigen GROUP BY-Vorgängen von MySQL implizit enthalten war. Der Server kann einen beliebigen Wert für die Rückgabe auswählen.

7
O. Jones

Als Erstes muss man sehen, warum es so ist. Frühere Versionen erlaubten uns, etwas nachlässig zu sein: Während die Werte der gruppierten Spalte im Ergebnis vollständig (jeweils ohne Ausnahme) aufgelistet sind, werden die Werte der anderen ausgewählten Spalte (n) mehr oder weniger ausgelassen - aber der Code kann dies Welche (n) möchte ich Ihnen nicht sagen:

- Hey, MYSQL, list the families of the street - but add a first name as well to every row.
- Okay sir, but shall I use the father's or the mother's or...? I'm a machine, give exact orders!

Nachdem wir nun den Grund verstanden haben, können wir entscheiden, ob wir Präferenzen in Bezug auf die anderen Spalten haben. Benutzen

MAX() AS
MIN() AS
etc, works with strings, too

oder wenn es wirklich gleich ist, z. Es gibt keinen Unterschied zwischen den nicht aggregierten Werten, die sich auf die gruppierten Werte beziehen, use

ANY_VALUE() AS

Auf jeden Fall lassen Sie mysql wissen, dass Sie wissen, dass es sich um "zweideutig" handelt, aber Sie möchten sich nicht auf alle Spalten konzentrieren, außer auf die von Ihnen gruppierten Spalten.

0
Szél Lajos

Eine andere Lösung, die oben mehrfach erwähnt wurde, besteht darin, dieses nervige 'ONLY_FULL_GROUP_BY' auszuschalten, z. wie in diesem Beitrag: ONLY_FULL_GROUP_BY deaktivieren

Ich denke, diese Lösung ist sehr nützlich, wenn Sie das gesamte Projekt nicht für mehrere Stunden umgestalten möchten. Und wenn Sie sich nicht für die unvorhersehbaren Werte der Spalten interessieren, die keine Liste der GROUP BY sind.

0
Juri Sinitson