Facciamo finta che vuoi visualizzare una pagina di riassunto dell'utente Bepi Xausa
Puoi fare più query (di tipo semplice):
codice:
SELECT * FROM utenti WHERE id='2';
Questa riga restituisce i dati dell'utente bepi, ma devi prendere anche il nome del comune e della provincia perchè devi visualizzarli. Quindi fai anche le seguenti query:
codice:
SELECT * FROM comuni WHERE id='$idcomune';
SELECT * FROM province WHERE id='$idprovincia';
Come funziona?
Dalla prima query trovi tutti i dati di bepi incluso l'id del suo comune. Con l'id del comune, tramite la seconda query, trovi sia il nome del comune che l'id della provincia. Con l'id della provincia e la terza query trovi in fine anche il nome della provincia.
Tuttavia puoi sostituire le tre query viste sopra con query un po' più complesse che riescono ad estrapolare dati in modo più efficace anche se richiedono una certa pratica per essere utilizzate:
codice:
SELECT utenti.nome, utenti.cognome, comuni.nome AS comune, province.nome AS provincia FROM utenti, comuni, province WHERE utenti.id='1' AND comuni.id=utenti.idcomune AND province.id=comuni.idprovincia;
Con quest'ultima query il database ti restituirà tutto quello che ti serve senza bisogno di fare richieste multiple. Quindi la cosa diviene anche più performante.
Ti basterà fare così per avere quello che ti interessa riguardo a Bepi.
codice:
$result=mysql_query(ULTIMA_SQL);
$rs=mysql_fetch_object($result);
print "L'utente ".$rs->nome.' '.$rs->cognome.' abita a '.$rs->comune.' nella provincia di '.$rs->provincia;
Questa operazione è detta join, cioè si produce un set di risultati colleganto i record (righe) di una tabella con quelli di un altra.
Come funziona?
Chiediamo al db di restituire il campo "nome" della tabella utenti con utenti.nome e facciamo lo stesso con il cognome. Chiediamo anche di restituire "nome" della tabella comuni creando un alias con la direttiva AS. Usiamo l'alias perchè inserire in un set di risultati due campi con lo stesso nome non è possibile. Con "AS comune" diciamo al db di dare ai risultati del campo comuni.nome un nuovo nominativo, in questo caso "comune". Infatti poi useremo "comune" da php per ottenere il valore. Facciamo lo stesso con province.nome rinominandole in "provincia".
A questo punto diciamo in che tabelle cercare con FROM e le separiamo con una virgola.
Con WHERE poi specifichiamo dove selezionare i risultati.
Quando specifichi un campo di una tabella dopo where lavorando con tabelle multiple il db prende in considerazione la prima che coincide e procede con le altre (almeno in teoria).
Ecco come funziona:
-C'è solo una clausola che riguarda la tabella utenti nel WHERE. E' utenti.id='1'. Questa è immediatamente soddisfabile quindi il database si porta nel record dell'utente 1 (Bepi). Ha già soddisfatto i primi requisiti del SELECT (ossia utenti.nome, utenti.cognome). Ora procede ad analizzare la clausola WHERE.
-Trova una nuova condizione da soddisfare che riguarda i comuni: AND comuni.id=utenti.idcomune. "utenti.idcomune" è un valore noto perchè il db si è già fermato all'utente Bepi nella tabella utenti. Ecco quindi che il db sa anche in che riga fermarsi sulla tabella comuni per prendere comuni.nome. Procede ad analizzare il WHERE.
-Trova un altra condizione da soddisfare: AND province.id=comuni.idprovincia. Cerca nella tabella province dove esiste una riga con id pari a "comuni.idprovincia" che ha prelevato nel punto precedente e così, avendo individuato una riga anche per la tabella provincie finisce di soddisfare i requisiti del SELECT.
Non ti spaventare cmq per la complessità di questa query "tutto in uno"
Quasi nessuno ha bisogno di ottimizzare così tanto gli accessi al database. Puoi tranquillamente fare delle query multiple ed anche se farai qualche richiesta in più non te ne accorgerai nemmeno a livello di performance e non rischierai di incappare in logoranti "bombe logiche".
Esistono altri metodi ancora più complessi per utilizzare interrogare un database, come le query innestate, ma io non le ho mai utilizzate perchè è difficile averne veramente bisogno e soprattutto non tutti i database le supportano..