MySQL :: MySQL 5.6 Reference Manual :: 12.19.3 MySQL Handling of GROUP BY
12.19.3 MySQL Handling of GROUP BY
in standard SQL kan een query die een GROUP BY
clausule bevat niet verwijzen naar niet-aggregated columns in de select list die niet genoemd worden in deGROUP BY
clausule. Deze query is bijvoorbeeld illegaal in standaard SQL omdat de niet-samengevoegde name
kolom in de select lijst niet voorkomt in de GROUP BY
:
SELECT o.custid, c.name, MAX(o.payment) FROM orders AS o, customers AS c WHERE o.custid = c.custid GROUP BY o.custid;
om de zoekopdracht legaal te maken, moet de kolom name
worden weggelaten uit de select list of worden genoemd in de GROUP BY
clausule.
MySQL breidt het standaard SQL gebruik van GROUP BY
uit zodat de select lijst kan verwijzen naar niet-samengevoegde kolommen die niet genoemd zijn in de GROUP BY
clausule. Dit betekent dat de voorgaande query legaal is in MySQL. U kunt deze functie gebruiken om betere prestaties te krijgen door onnodig sorteren en groeperen van kolommen te vermijden. Dit is echter vooral nuttig wanneer alle waarden in elke niet-geaggregeerde kolom die niet genoemd wordt in de GROUP BY
voor elke groep hetzelfde zijn. De server is vrij om elke waarde uit elke groep te kiezen, dus tenzij ze hetzelfde zijn, zijn de gekozen waarden niet-deterministisch. Bovendien kan de selectie van waarden uit elke groep niet worden beïnvloed door het toevoegen van een ORDER BY
clausule. Het sorteren van de resultaatset vindt plaats nadat waarden zijn gekozen, en ORDER BY
heeft geen invloed op welke waarden binnen elke groep de server kiest.
een soortgelijke MySQL extensie is van toepassing op de HAVING
clausule. In standaard SQL kan een query niet verwijzen naar niet-samengevoegde kolommen in de HAVING
clausule die niet genoemd worden in de GROUP BY
clausule. Om berekeningen te vereenvoudigen, staat een MySQL extensie verwijzingen naar dergelijke kolommen toe. Deze extensie gaat ervan uit dat de niet-gegroepeerde kolommen dezelfde groepswaarden hebben. Anders is het resultaat niet-deterministisch.
om de MySQL GROUP BY
extensie uit te schakelen en standaard SQL-gedrag aan te zetten, schakelt u de ONLY_FULL_GROUP_BY
SQL-modus in. In dit geval kunnen kolommen die niet zijn genoemd in de GROUP BY
– clausule niet worden gebruikt in de select list of HAVING
– clausule, tenzij ze zijn ingesloten in een aggregaatfunctie.
de extensie select list is ook van toepassing op ORDER BY
. Dat wil zeggen, U kunt verwijzen naar niet-samengevoegde kolommen in de ORDER BY
clausule die niet voorkomen in de GROUP BY
clausule. (Echter, zoals eerder vermeld, heeft ORDER BY
geen invloed op welke waarden worden gekozen uit niet-geaggregeerde kolommen; het sorteert ze alleen nadat ze zijn gekozen.) Deze extensie is niet van toepassing als de ONLY_FULL_GROUP_BY
SQL-modus is ingeschakeld.
als een query geaggregeerde functies heeft en geen GROUP BY
clausule, kan het geen niet-geaggregeerde kolommen in de select lijst hebben, HAVING
voorwaarde, of ORDER BY
lijst met ONLY_FULL_GROUP_BY
ingeschakeld:
mysql> SELECT name, MAX(age) FROM t;ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)with no GROUP columns is illegal if there is no GROUP BY clause
zonder GROUP BY
is er één groep en het is niet-deterministisch welke name
waarde voor de groep moet worden gekozen.
een andere MySQL-extensie voor standaard SQL staat verwijzingen toe in de HAVING
clausule naar aliased expressies in de select lijst. Het inschakelen van ONLY_FULL_GROUP_BY
voorkomt dit. De volgende query geeft bijvoorbeeld name
waarden terug die slechts één keer voorkomen in tabel orders
; de query wordt geaccepteerd ongeacht of ONLY_FULL_GROUP_BY
is ingeschakeld:
SELECT name, COUNT(name) FROM orders GROUP BY name HAVING COUNT(name) = 1;
de volgende query wordt alleen geaccepteerd als ONLY_FULL_GROUP_BY
is uitgeschakeld.
SELECT name, COUNT(name) AS c FROM orders GROUP BY name HAVING c = 1;
Als u probeert standaard SQL te volgen, kunt u alleen kolomuitdrukkingen gebruiken in GROUP BY
clausules. Gebruik als tijdelijke oplossing een alias voor de uitdrukking:
SELECT id, FLOOR(value/100) AS val FROM tbl_name GROUP BY id, val;
MySQL staat niet-kolomn expressies toe in GROUP BY
clausules, zodat de alias niet nodig is:
SELECT id, FLOOR(value/100) FROM tbl_name GROUP BY id, FLOOR(value/100);
Leave a Reply