MySQL :: MySQL 5.6 Manuale di Riferimento :: 12.19.3 MySQL Gestione del GRUPPO DA
12.19.3 MySQL Gestione del GRUPPO DA parte di
In SQL standard, una query che include un GROUP BY
clausola non può fare riferimento a nonaggregated colonne dell’elenco di selezione che non sono denominati nel GROUP BY
clausola. Ad esempio, questa query è illegale in SQL standard perché la colonna non segregata name
nell’elenco di selezione non viene visualizzata in 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;
Affinché la query sia legale, la colonna name
deve essere omessa dall’elenco di selezione o nominata nella clausola GROUP BY
.
MySQL estende l’uso SQL standard di GROUP BY
in modo che l’elenco di selezione possa fare riferimento a colonne non aggregate non nominate nella clausolaGROUP BY
. Ciò significa che la query precedente è legale in MySQL. È possibile utilizzare questa funzione per ottenere prestazioni migliori evitando l’ordinamento e il raggruppamento delle colonne non necessari. Tuttavia, questo è utile principalmente quando tutti i valori in ogni colonna non aggregata non denominata in GROUP BY
sono gli stessi per ogni gruppo. Il server è libero di scegliere qualsiasi valore da ciascun gruppo, quindi a meno che non siano uguali, i valori scelti non sono deterministici. Inoltre, la selezione dei valori di ciascun gruppo non può essere influenzata aggiungendo una clausolaORDER BY
. L’ordinamento dei set di risultati si verifica dopo la scelta dei valori e ORDER BY
non influisce sui valori all’interno di ciascun gruppo scelto dal server.
Un’estensione MySQL simile si applica alla clausolaHAVING
. In SQL standard, una query non può fare riferimento a colonne non aggregate nella clausolaHAVING
che non sono nominate nella clausolaGROUP BY
. Per semplificare i calcoli, un’estensione MySQL consente riferimenti a tali colonne. Questa estensione presuppone che le colonne non raggruppate abbiano gli stessi valori di gruppo. Altrimenti, il risultato è non deterministico.
Per disabilitare l’estensione MySQL GROUP BY
e abilitare il comportamento SQL standard, abilitare la modalità SQL ONLY_FULL_GROUP_BY
. In questo caso, le colonne non nominate nella clausola GROUP BY
non possono essere utilizzate nella clausola select list o HAVING
a meno che non siano racchiuse in una funzione aggregata.
L’estensione select list si applica anche a ORDER BY
. Cioè, è possibile fare riferimento a colonne non aggregate nella clausola ORDER BY
che non appaiono nella clausola GROUP BY
. (Tuttavia, come accennato in precedenza,ORDER BY
non influisce sui valori scelti dalle colonne non segregate; li ordina solo dopo che sono stati scelti.) Questa estensione non si applica se la modalità SQLONLY_FULL_GROUP_BY
è abilitata.
Se una query ha funzioni aggregate e nessuna clausola GROUP BY
, non può avere colonne non aggregate nell’elenco di selezione,HAVING
condizione, o ORDER BY
elenco con ONLY_FULL_GROUP_BY
abilitato:
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
Senza GROUP BY
, esiste un singolo gruppo e non è deterministico quale valore name
scegliere per il gruppo.
Un’altra estensione MySQL per SQL standard consente riferimenti nella clausolaHAVING
alle espressioni con alias nell’elenco select. Abilitare ONLY_FULL_GROUP_BY
impedisce questo. Ad esempio, la seguente query restituiscename
valori che si verificano solo una volta nella tabella orders
; la query viene accettata indipendentemente dal fatto che ONLY_FULL_GROUP_BY
sia abilitata:
SELECT name, COUNT(name) FROM orders GROUP BY name HAVING COUNT(name) = 1;
La seguente query viene accettata solo se ONLY_FULL_GROUP_BY
è disabilitata.
SELECT name, COUNT(name) AS c FROM orders GROUP BY name HAVING c = 1;
Se si sta tentando di seguire SQL standard, è possibile utilizzare solo espressioni di colonna nelle clausoleGROUP BY
. Come soluzione alternativa, utilizzare un alias per l’espressione:
SELECT id, FLOOR(value/100) AS val FROM tbl_name GROUP BY id, val;
MySQL consente espressioni non di colonna in GROUP BY
clausole, quindi l’alias non è necessario:
SELECT id, FLOOR(value/100) FROM tbl_name GROUP BY id, FLOOR(value/100);
Leave a Reply