Articles

Mysql :: MySQL 5.6 referenshandbok :: 12.19.3 MySQL hantering av grupp med

12.19.3 MySQL hantering av grupp med

i standard SQL kan en fråga som innehåller en GROUP BYklausul inte hänvisa till icke-aggregerade kolumner i select lista som inte nämns iGROUP BYklausul. Till exempel är denna fråga olaglig i standard SQL eftersom den icke-aggregerade name kolumnen i select-listan inte visas i 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;

för att frågan ska vara laglig måstename kolumnen utelämnas från select-listan eller namnges iGROUP BY klausulen.

MySQL utökar standard SQL-användningen avGROUP BY så att select-listan kan referera till icke-aggregerade kolumner som inte nämns iGROUP BY – klausulen. Detta innebär att den föregående frågan är laglig i MySQL. Du kan använda den här funktionen för att få bättre prestanda genom att undvika onödig kolumnsortering och gruppering. Detta är dock användbart främst när alla värden i varje icke-aggregerad kolumn som inte nämns i GROUP BY är desamma för varje grupp. Servern är fri att välja vilket värde som helst från varje grupp, så om de inte är desamma är de valda värdena nondeterministiska. Dessutom kan valet av värden från varje grupp inte påverkas genom att lägga till en ORDER BY – klausul. Resultatuppsättning sortering sker efter att värden har valts och ORDER BY påverkar inte vilka värden inom varje grupp servern väljer.

en liknande MySQL-förlängning gällerHAVING – klausulen. I standard SQL kan en fråga inte hänvisa till icke-aggregerade kolumner i HAVING – klausulen som inte heter i GROUP BY – klausulen. För att förenkla beräkningarna tillåter en MySQL-förlängning hänvisningar till sådana kolumner. Denna förlängning förutsätter att de icke-grupperade kolumnerna har samma gruppvisa värden. Annars är resultatet nondeterministiskt.

för att inaktivera MySQL GROUP BY förlängning och aktivera standard SQL-beteende, aktivera ONLY_FULL_GROUP_BY SQL-läge. I det här fallet kan kolumner som inte nämns i GROUP BY – klausulen inte användas i select-listan ellerHAVING – klausulen om de inte är inneslutna i en aggregerad funktion.

select list-tillägget gäller även ORDER BY. Det vill säga Du kan hänvisa till icke-aggregerade kolumner i ORDER BY – klausulen som inte visas i GROUP BY – klausulen. (Som tidigare nämnts påverkar emellertid ORDER BY inte vilka värden som väljs från icke-aggregerade kolumner; det sorterar dem bara efter att de har valts.) Detta tillägg gäller inte om ONLY_FULL_GROUP_BY SQL-läget är aktiverat.

om en fråga har aggregerade funktioner och ingenGROUP BY klausul, kan den inte ha icke-aggregerade kolumner i select-listan,HAVING villkor ellerORDER BY lista medONLY_FULL_GROUP_BY aktiverad:

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

utan GROUP BY, det finns en enda grupp och det är nondeterministiskt vilket name värde att välja för gruppen.

en annan MySQL-förlängning till standard SQL tillåter referenser iHAVING klausul till aliaserade uttryck i select-listan. Att aktivera ONLY_FULL_GROUP_BY förhindrar detta. Till exempel returnerar följande fråga name värden som bara förekommer en gång i tabellen orders; frågan accepteras oavsett om ONLY_FULL_GROUP_BY är aktiverat:

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

följande fråga accepteras endast om ONLY_FULL_GROUP_BY är inaktiverat.

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

Om du försöker följa standard SQL kan du bara använda kolumnuttryck i GROUP BY klausuler. Som en lösning, Använd ett alias för uttrycket:

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

MySQL tillåter icke-kolumnuttryck iGROUP BY klausuler, så aliaset är onödigt:

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