Questa settimana, durante la stesura di un progetto come Programmatore PHP Freelance, mi sono imbattuto nella necessità di selezionare più righe con una Query utilizzando MySQL.
Visto che la cosa può non risultare intuitiva, ho deciso di scrivere una breve Guida MySQL per spiegare come poter selezionare diverse righe della stessa tabella e raggrupparle per un determinato valore.
Esempio Pratico:
Supponiamo di avere una tabella padri e una tabella figli:
Padri
id nome paese lavoro
1 Luigi Roma Impiegato
2 Michele Milano Programmatore
3 Antonio Roma Operaio
4 Roberto Napoli Impiegato
Figli
id idPadre nome
1 1 Giulio
2 1 Aldo
3 2 Lucilla
4 3 Giulio
5 4 Aristide
6 4 Aldo
7 3 Paolo
8 3 Aldo
Supponiamo di volere selezionare dal nostro database MySQL tutti gli id padre di quei padri che abbiano un figlio di nome Giulio e un figlio di nome Aldo. A occhio potrebbe risultare molto facile, ma come tramutare il nostro pensiero in codice SQL?
La soluzione che ho studiato e implementato è la seguente, ma ovviamente nulla vieta di trovare soluzioni alternative (e magari segnalarle in modo da inserire il questo articolo).
Procediamo con una prima tappa e proviamo a selezionare prima tutti gli utenti che hanno un figlio di nome Aldo:
SELECT idPadre, GROUP_CONCAT( nome
ORDER BY nome ) AS listaFigli
FROM figli
GROUP BY idPadre
HAVING find_in_set( 'Aldo', listaFigli );
Otterremo come risultati:
idPadre listaFigli
1 Aldo,Giulio
2 Aldo
3 Aldo,Giulio,Paolo
Ma passiamo in dettaglio a spiegare la query MySQL che utilizza qualche specifica non utilizzata da molti Programmatori alle prime esperienze:
Con la specifica GROUP_CONCAT( nome ORDER BY nome )ordiniamo tutti i nomi in ordine alfabetico relativi all'idPadre, tale array presenta come separatore di default la virgola, ma è possibile aggiungere un parametro che ne specifica uno diverso.
Con GROUP BY raggruppiamo per idPadre e aggiungiamo la clausola essenziale cioè che abbiano (HAVING) il valore aldo nella listaFigli e in questo caso abbiamo utilizzato l'interessantissima funzione MySQL find_in_set che ricerca un valore in un array.
E intuitivo da capire per un Programmatore MySQL Esperto o meno esperto che basta modificare questa query aggiungendo una nuova clausola find_in_set per ottenere ciò di cui abbiamo bisogno:
SELECT id_padre, GROUP_CONCAT( nome
ORDER BY nome ) AS listanomi
FROM figli
GROUP BY id_Padre
HAVING find_in_set( 'Aldo', listanomi )
AND find_in_set( 'Giulio', listanomi )
e così via fino a raggiungere la selezione desiderata.
Spero di essere stato utile con questa selezione di più righe con MySql. Più avanti potrei presentare un piccolo script nella sezione Programmatore PHP che possa rendere dinamico da codice PHP l'incremento o il decremento del filtro find_in_set.

danilo - Inserito il: 09/12/10
Buongiorno. Da poco mi sono addentrato nel mondo di php e mysql e devo dire che è interessante. Navigando in rete cercadno una soluzione al mio problema ho trovato il suo sito e mi sonom esso a leggere un po di articoli. Alcuni mi sono stati davvero utili!! Vengo al punto: praticamente io ho un form che una volta compilato mi restituisce un valore; questo valore mi servirebbe per vedere se esiste all'interno di 6 tabelle. Il problema mi si pone in quanto i campi delle tabelle, nelle quali devo cercare se esiste il valore o meno, si chiamano in modo differente. La mia domanda è: come posso ottimizzare con una sola query tale richiesta? E poi, è possibile farla? Ho pensato di scrivere il commento in questo articolo perchè mi sembrava il più adatto e soprattutto perchè se c'è una soluzione e magari mi aiutasse a trovarla credo che sarebbe molto utile a tantissimi altri utenti. La ringrazio anticipatamente per il suo aiuto.