Articles

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, a query that including a GROUP BY clause ei voi viitata nonaggregated valitse-luettelon sarakkeet, joita ei ole nimetty GROUP BY lausekkeessa. Esimerkiksi tämä kysely on lainvastainen vakio-SQL: ssä, koska ei-aggregoitu name sarake valitussa luettelossa ei näy 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;

jotta kysely olisi laillinen, name sarake on jätettävä pois select-luettelosta tai nimettävä GROUP BY lauseke.

MySQL laajentaa SQL: n standardikäyttöä GROUP BY siten, että select-lista voi viitata ei-eroteltuihin sarakkeisiin, joita ei ole nimetty GROUP BY lausekkeessa. Tämä tarkoittaa, että edellinen kysely on laillinen MySQL. Voit käyttää tätä ominaisuutta saadaksesi paremman suorituskyvyn välttämällä tarpeetonta sarakkeiden lajittelua ja ryhmittelyä. Tämä on kuitenkin hyödyllistä ensisijaisesti silloin, kun kaikki arvot kussakin ei-erotellussa sarakkeessa, joita ei ole nimetty GROUP BY, ovat samat kullekin ryhmälle. Palvelin voi vapaasti valita minkä tahansa arvon jokaisesta ryhmästä, joten elleivät ne ole samat, valitut arvot ovat nondeterministisiä. Lisäksi arvojen valintaan kustakin ryhmästä ei voi vaikuttaa lisäämällä ORDER BY lauseke. Tulosjoukon lajittelu tapahtuu arvojen valinnan jälkeen, eikä ORDER BY vaikuta siihen, mitkä arvot kussakin ryhmässä palvelin valitsee.

vastaava MySQL-laajennus pätee HAVING – lausekkeeseen. Standardissa SQL: ssä kysely ei voi viitata HAVING lausekkeessa ei ole nimetty GROUP BY lausekkeessa. Laskentojen yksinkertaistamiseksi MySQL-laajennus sallii viittaukset tällaisiin sarakkeisiin. Tämä laajennus olettaa, että ei-ryhmitetyillä sarakkeilla on samat ryhmäarvot. Muuten tulos on nondeterministinen.

Jos haluat poistaa MySQL: n GROUP BY laajennuksen ja ottaa käyttöön SQL: n vakiokäyttäytymisen, Ota käyttöön ONLY_FULL_GROUP_BY SQL-tila. Tällöin sarakkeita, joita ei ole nimetty GROUP BY lausekkeessa, ei voi käyttää select-luettelossa tai HAVING lausekkeessa, ellei niitä ole liitetty yhteen funktioon.

select list-laajennus koskee myös ORDER BY. Toisin sanoen ORDER BY lausekkeessa voidaan viitata ei-eroteltuihin sarakkeisiin, jotka eivät esiinny GROUP BY lausekkeessa. (Kuitenkin, kuten aiemmin mainittiin, ORDER BY ei vaikuta siihen, mitkä arvot valitaan ei-erotelluista sarakkeista; se lajittelee ne vasta sen jälkeen, kun ne on valittu.) Tämä laajennus ei päde, jos ONLY_FULL_GROUP_BY SQL-tila on käytössä.

Jos kyselyssä on aggregoituja funktioita ja ei GROUP BY lauseke, sillä ei voi olla ei-aggregoituja sarakkeita select list, HAVING condition, tai ORDER BY list with ONLY_FULL_GROUP_BY enabled:

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

ilman GROUP BY on olemassa yksi ryhmä ja on epädeterministinen, mikä name arvo valita ryhmälle.

toinen MySQL-laajennus standardiin SQL sallii HAVING – lausekkeen viittaukset aliasennettuihin lausekkeisiin valitussa luettelossa. Ottaminen käyttöön ONLY_FULL_GROUP_BY estää tämän. Esimerkiksi seuraava kysely palauttaa name arvot, jotka esiintyvät vain kerran taulukossa orders; kysely hyväksytään riippumatta siitä, onko ONLY_FULL_GROUP_BY käytössä:

SELECT name, COUNT(name) FROM orders GROUP BY name HAVING COUNT(name) = 1;

seuraava kysely hyväksytään vain, jos ONLY_FULL_GROUP_BY on pois käytöstä.

SELECT name, COUNT(name) AS c FROM orders GROUP BY name HAVING c = 1;

Jos yrität noudattaa standardisql: ää, voit käyttää GROUP BY lausekkeita. Käytä peitenimeä lausekkeelle:

SELECT id, FLOOR(value/100) AS val FROM tbl_name GROUP BY id, val;

MySQL sallii noncolumn lausekkeet GROUP BY lausekkeet, joten peitenimi on tarpeeton:

SELECT id, FLOOR(value/100) FROM tbl_name GROUP BY id, FLOOR(value/100);