- clorophilla.blog - https://www.clorophilla.net/blog -

Funzione GROUP_CONCAT in MySQL

In MySQL, dalla versione 4.1 in avanti, è presente una funzione di aggregazione spesso trascurata ma che in alcuni casi può tornare molto utile per la sua comodità (si sta parlando di codice SQL non standard), mi riferisco alla funzione GROUP_CONCAT. Molto semplicemente questa funzione si occupa di concatenare gli elementi di un gruppo, per esempio le righe restituite da una sub-query, in un'unica stringa con la possibilità di specificare un separatore per l'unione dei vari elementi. Facciamo un esempio, supponiamo di avere tre tabelle: una che definisce l'elenco di utenti, una che definisce una serie di hobby e infine un'altra tabella ponte che mette in relazione utenti con i relativi hobby e ci permetta quindi di definire una relazione molti-a-molti. Ecco come potrebbe apparire la struttura delle nostre tabelle, in maniera molto semplificata:

CREATE TABLE `hobby` ( `IdHobby` int(10) unsigned NOT NULL auto_increment, `Nome` varchar(45) NOT NULL default '', PRIMARY KEY (`IdHobby`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `utenti` ( `IdUtente` int(10) unsigned NOT NULL auto_increment, `Nome` varchar(60) NOT NULL default '', `Email` varchar(50) NOT NULL default '', PRIMARY KEY (`IdUtente`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `utenti_hobby` ( `IdUtente` int(10) unsigned NOT NULL default '0', `IdHobby` int(10) unsigned NOT NULL default '0', PRIMARY KEY (`IdUtente`,`IdHobby`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

A questo punto inseriamo un pò di dati a nostro piacimento e creiamo la nostra query di selezione sfruttando la funzione GROUP_CONCAT:

SELECT u.Nome, ( SELECT GROUP_CONCAT(h.Nome ORDER BY h.Nome ASC SEPARATOR ', ') FROM utenti_hobby AS uh JOIN hobby AS h ON h.IdHobby = uh.IdHobby WHERE uh.IdUtente = u.IdUtente ) AS Hobby FROM utenti AS u;

Ecco cosa otteniamo come risultato:

+---------+-----------------------------------+
| Nome    | Hobby                             |
+---------+-----------------------------------+
| Luigi   | Calcio, Informatica, Pesca        |
| Mario   | Automobilismo, Calcio             |
| Claudio | Automobilismo, Informatica, Pesca |
+---------+-----------------------------------+
3 rows in set (0.00 sec)

Come è possibile notare la funzione GROUP_CONCAT permette di indicare anche quale ordinamento dare agli elementi soggetti alla concatenazione. Avremmo potuto certamente ottenere lo stesso risultato specificando l'ordinamento al livello della sub-select, l'unica differenza nella realtà risiede nel fatto che in questo caso MySQL avrebbe creato una tabella temporanea per effettuare l'ordinamento mentre ciò non avviene con GROUP_CONCAT (basta effettuare l'EXPLAIN delle due query per notarlo). Per maggiori informazioni è possibile consultare la documentazione di questa funzione dal sito di MySQL nella sezione riguardante le funzioni di aggregazione [1], cercando appunto GROUP_CONCAT all'interno della pagina. In allegato vi fornisco anche lo script sql [2] per ricreare il semplice database che ho usato come esempio.

2 Comments (Open | Close)

2 Comments To "Funzione GROUP_CONCAT in MySQL"

#1 Comment By beppe On 24 maggio 2007 @ 12:16

ottima risorsa...ma il mio server non supporta questa funzione...c'e un'alternativa x ottenere lo stesso risultato su un mysql iu datato?

#2 Comment By NRK On 25 maggio 2007 @ 12:01

Da MySQL versione 3.23 in poi è possibile aggiungere funzioni personalizzate con il sistema [3] e usando questo sistema si può programmare e caricare un'estensione che replichi le funzionalità di GROUP_CONCAT con versioni di MySQL inferiori alla 4.1. Ho trovato [4] che prende in esame proprio un'estensione UDF per GROUP_CONCAT, purtroppo non ho modo di provarla però spero possa tornarti utile.