Articles

5.6 Referencehåndbog :: 12.19.3 håndtering af gruppe af

12.19.3 håndtering af gruppe af

i standard KVM kan en forespørgsel, der indeholder en GROUP BYklausul, ikke se ikke-aggregerede kolonner på listen Vælg, der ikke er navngivet iGROUP BYklausul. For eksempel er denne forespørgsel ulovlig i STANDARDKVL, fordi den ikke-aggregeredename kolonne I select list vises ikke 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;

for at forespørgslen skal være lovlig, skal kolonnenname udelades fra select list eller navngives iGROUP BY klausul.

Vi udvider standard brugen afGROUP BY så select list kan henvise til ikke-aggregerede kolonner, der ikke er navngivet iGROUP BY klausul. Dette betyder, at den foregående forespørgsel er lovlig i Myskl. Du kan bruge denne funktion til at få bedre ydeevne ved at undgå unødvendig kolonnesortering og gruppering. Dette er dog primært nyttigt, når alle værdier i hver ikke-aggregeret kolonne, der ikke er navngivet i GROUP BY er de samme for hver gruppe. Serveren kan frit vælge en hvilken som helst værdi fra hver gruppe, så medmindre de er de samme, er de valgte værdier ikke-deterministiske. Desuden kan valget af værdier fra hver gruppe ikke påvirkes ved at tilføje en ORDER BY klausul. Resultat sæt sortering sker efter værdier er blevet valgt, og ORDER BY påvirker ikke, hvilke værdier inden for hver gruppe Serveren vælger.

en lignende udvidelse gælder forHAVING klausulen. En forespørgsel kan ikke henvise til ikke-aggregerede kolonner i HAVING – klausulen, der ikke er navngivet i GROUP BY – klausulen. For at forenkle beregningerne tillader en udvidelse henvisninger til sådanne kolonner. Denne udvidelse forudsætter, at de ikke-grupperede kolonner har de samme gruppevis værdier. Ellers er resultatet ikke-deterministisk.

Hvis du vil deaktivere mysklGROUP BYudvidelse og aktivere standardkvl-adfærd, skal du aktivereONLY_FULL_GROUP_BY KVL-tilstand. I dette tilfælde kan kolonner, der ikke er navngivet i GROUP BY – klausulen, ikke bruges i select list eller HAVING – klausulen, medmindre den er lukket i en aggregeringsfunktion.

udvidelsen select list gælder også forORDER BY. Det vil sige, du kan henvise til ikke-aggregerede kolonner i ORDER BY klausul, der ikke vises i GROUP BY klausul. (Som tidligere nævnt påvirker ORDER BY ikke, hvilke værdier der vælges fra ikke-aggregerede kolonner; det sorterer dem kun, efter at de er valgt.) Denne udvidelse gælder ikke, hvis tilstanden ONLY_FULL_GROUP_BY er aktiveret.

Hvis en forespørgsel har aggregeringsfunktioner og ingenGROUP BY klausul, kan den ikke have ikke-aggregerede kolonner i select list, HAVING betingelse eller ORDER BY liste med ONLY_FULL_GROUP_BY aktiveret:

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

udenGROUP BY, der er en enkelt gruppe, og det er ikke deterministisk, somname værdi at vælge for gruppen.

en anden udvidelse til standardkvl tillader referencer iHAVING klausul til alias udtryk i select list. Aktivering af ONLY_FULL_GROUP_BY forhindrer dette. For eksempel returnerer følgende forespørgsel name værdier, der kun forekommer en gang i tabel orders; forespørgslen accepteres uanset om ONLY_FULL_GROUP_BY er aktiveret:

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

følgende forespørgsel accepteres kun, hvis ONLY_FULL_GROUP_BY er deaktiveret.

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

Hvis du forsøger at følge standardkvl, kan du kun bruge kolonneudtryk iGROUP BY klausuler. Som en løsning skal du bruge et alias til udtrykket:

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

Myskl tillader ikke-kolonneudtryk i GROUP BY klausuler, så aliaset er unødvendigt:

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