Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL GROUP BY-Verhalten

MySQL wählt eine Zeile willkürlich aus. In der Praxis geben häufig verwendete MySQL-Speicher-Engines die Werte vom ersten zurück Zeile in der Gruppe in Bezug auf den physischen Speicher.

create table foo (id serial primary key, category varchar(10));

insert into foo (category) values 
  ('foo'), ('foo'), ('foo'), ('bar'), ('bar'), ('bar');

select * from foo group by category;

+----+----------+
| id | category |
+----+----------+
|  4 | bar      |
|  1 | foo      |
+----+----------+

Andere Leute haben Recht damit, dass MySQL es Ihnen erlaubt, diese Abfrage auszuführen, obwohl sie willkürliche und möglicherweise irreführende Ergebnisse liefert. Der SQL-Standard und die meisten anderen RDBMS-Anbieter verbieten diese Art mehrdeutiger GROUP BY-Abfragen. Dies wird als Einzelwertregel bezeichnet :Alle Spalten in der Auswahlliste müssen explizit Teil des GROUP BY-Kriteriums sein oder sich innerhalb einer Aggregatfunktion befinden, z. COUNT() , MAX() usw.

MySQL unterstützt einen SQL-Modus ONLY_FULL_GROUP_BY Dadurch gibt MySQL einen Fehler zurück, wenn Sie versuchen, eine Abfrage auszuführen, die gegen die SQL-Standardsemantik verstößt.

AFAIK, SQLite ist das einzige andere RDBMS, das mehrdeutige Spalten in einer gruppierten Abfrage zulässt. SQLite gibt Werte vom letzten zurück Zeile in der Gruppe:

select * from foo group by category;

6|bar
3|foo

Wir können uns Abfragen vorstellen, die nicht mehrdeutig sind, aber dennoch gegen die SQL-Standardsemantik verstoßen.

SELECT foo.*, parent_of_foo.* 
FROM foo JOIN parent_of_foo 
  ON (foo.parent_id = parent_of_foo.parent_id) 
GROUP BY foo_id;

Es gibt keinen logischen Weg, wie dies zu mehrdeutigen Ergebnissen führen könnte. Jede Zeile in foo erhält ihre eigene Gruppe, wenn wir GROUP BY den Primärschlüssel von foo verwenden. Jede Spalte von foo kann also nur einen Wert in der Gruppe haben. Sogar das Verbinden mit einer anderen Tabelle, auf die durch einen Fremdschlüssel in foo verwiesen wird, kann nur einen Wert pro Gruppe haben, wenn die Gruppen durch den Primärschlüssel von foo definiert sind.

MySQL und SQLite vertrauen darauf, dass Sie logisch eindeutige Abfragen entwerfen. Formal muss jede Spalte in der Auswahlliste eine funktionale Abhängigkeit sein der Spalten in den GROUP BY-Kriterien. Wer sich nicht daran hält, ist selbst schuld. :-)

Standard-SQL ist strenger und verbietet einige Abfragen, die könnten eindeutig sein – wahrscheinlich, weil es für das RDBMS zu komplex wäre, um im Allgemeinen sicher zu sein.