Kurze Antwort
Es ist ein Speed-Hack
Diese Funktion ist standardmäßig aktiviert, kann aber mit dieser Einstellung deaktiviert werden: https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html
Lange Antwort Der Grund für die nicht standardmäßige Gruppierung nach der Klausel ist, dass es sich um einen Speed-Hack handelt.
MySQL lässt den Programmierer bestimmen, ob die ausgewählten Felder funktional von der Gruppenklausel abhängig sind.
Die DB führt keine Tests durch, sondern wählt einfach das erste Ergebnis, das sie findet, als Wert für das Feld aus.
Dies führt zu erheblichen Geschwindigkeitssteigerungen.
Betrachten Sie diesen Code:
SELECT f1, f2, f3, f4 FROM t1 GROUP BY f2
-- invalid in most SQL flavors, valid in MySQL
MySQL wählt einfach den ersten Wert aus, den es findet, und verbraucht so wenig Zeit wie möglich.
f1,f3, f4 stammen aus derselben Zeile, aber diese Beziehung fällt auseinander, wenn mehrere Tabellen mit Joins beteiligt sind.
Um das zu tun derselbe etwas Ähnliches in SQL-server müssten Sie tun
SELECT MIN(f1), f2, MIN(f3), MIN(f4) FROM t1 GROUP BY f2
-- valid SQL, but really a hack
Die DB wird nun prüfen müssen alle Ergebnisse, um den Mindestwert zu finden, und zwar mit Mühe und Not.
f1, f3, f4 haben höchstwahrscheinlich keine Beziehung zueinander und stammen nicht aus derselben Reihe.
Wenn Sie es dennoch tun:
SELECT id as `primary_key`, count(*) as rowcount, count(f2) as f2count, f2, f3, f4
FROM t1
GROUP BY id
Alle übrigen Felder sind funktional abhängig von id
.
Rowcount ist immer 1, und f2count ist entweder 0 (wenn f2 null ist) oder 1.
Bei Joins, an denen viele Tabellen beteiligt sind, in einer 1-n-Konfiguration wie hier:
Beispiel:
Website 1 -> n Themen 1 -> n Threads 1 -> n Beiträge 1 -> 1 Person.
Und Sie machen einen komplizierten Select, der alle Tabellen einbezieht, und machen einfach einen GROUP BY posts.id
Natürlich sind alle anderen Felder funktional von posts.id (und NUR von posts.id) abhängig.
Es macht also keinen Sinn, weitere Felder in der Gruppenklausel aufzuführen oder Sie zu zwingen, Aggregatfunktionen zu verwenden.
Um die Dinge zu beschleunigen. MySQL zwingt Sie nicht, dies zu tun.
Aber Sie do müssen das Konzept der funktionalen Abhängigkeit und die Beziehungen in den Tabellen und der von Ihnen geschriebenen Verknüpfung verstehen, so dass der Programmierer eine große Last zu tragen hat.
Allerdings mit:
SELECT
posts.id, MIN(posts.f2)
,MIN(threads.id), min(threads.other)
,MIN(topics.id), ....
,MIN(website.id), .....
,MIN(Person.id), ...
FROM posts p
INNER JOIN threads t on (p.thread_id = t.id)
INNER JOIN topic to on (t.topic_id = to.id)
INNER JOIN website w ON (w.id = to.website_id)
INNER JOIN person pe ON (pe.id = p.person_id)
GROUP BY posts.id //NEVER MIND THE SYNTAX ERROR WITH THE ALIASES
Für den Programmierer bedeutet das genau die gleiche mentale Belastung.