Normalizzazione tabelle

Gli argomenti di questa pagina

  • Normalizzazione delle tabelle
  • Struttura delle tabelle normalizzate
  • I files .sql che si useranno per la creazione delle tabelle
  • Metodi per creazione delle tabelle
  • Caso 1: creare le tabelle da pannello di controllo di phpmyadmin
  • Caso 2: creare le tabelle con script PHP
  • Caso 3: uso di Query CREATE TABLE per creare le tabelle
  • Importazione dei dati: INSERT e subquery
  • INSERT e subquery per la tabella sql_citta.
  • Importazione dei dati nella tabella sql_agenda: INSERT e subquery
  • Gli effetti delle operazioni compiute

In tutte le nostre prove abbiamo bisogno di questo file che mettiamo nella cartella res e che contiene tutte le credenziali per connetterci al nostro DB.

Il file db_login.php
1
2
3
4
5
6
<?php
$Host 
"hostname";
$User "username";
$Password "password";
$DBName "DBName";
?>

Normalizzazione delle tabelle

Il problema di questo esempio è l'opposto del precedente.
In questo esempio vorrei partire da una tabella dove ho memorizzato una semplice rubrica, esportando i dati in due altre tabelle correlate fra loro.
Immaginiamo di avere questa tabella chiamata sql_rubrica.

I campi della tabella sql_rubrica
id, codice, cognome, nome, indirizzo, cap, citta, prov, data_nascita, telefono

Da una rapida occhiata all'elenco dei campi è possibile notare che possiamo tirar fuori dalla tabella i campi cap, citta, prov e metterli in altra tabella: sql_citta.
Per non correre il rischio di derdere i dati con qualche operazione errata viene creata una nuova tabella chiamata sql_agenda copiandovi i campi della tabella aql_rubrica e, al posto dei campi cap, citta, prov, mettiamo un un campo id_citta che faccia riferimento al campo ID della tabella sql_citta come è visibile qui in basso.
Questo fatto porterà ad alcuni vantaggi:
In fase di registrazione o di modifica della tabella sql_agenda basterà indicare il solo id relativo a cap, citta, prov della tabella sql_citta (id_citta).
Se durante una registrazione o modifica sbagliamo l'associazione o l'ortografia di cap, citta, prov, basterà modificarli nella sola tabella sql_citta evitando di trovare eventuali errori in tutta la tabella.
Viene evitato che a più contatti della stessa città vengano attribuiti cap o provincia errati.
Nella normalizzazione delle tabelle potremmo scendere anche più a fondo, andando magari a valutare la estrapolazione dei telefoni, ma per il momento possiamo anche fermarci a questo punto.

I campi della tabella: sql_citta
id, cap, citta, prov

I campi della tabella: sql_agenda
id, cognome, nome, indirizzo, id_citta, data_nascita, telefono

Struttura delle tabelle normalizzate

Vediamo ora la struttura che potrebbero avere le tabella da creare.
In queste due tabelle, oltre agli ID presenti in entrambe, ed ai campi specifici di ciascuna tabella, c'è da notare il campo "id_citta" della tabella "sql_agenda". Questo campo serve da collegamento tra la tabella "sql_agenda" e la tabella "sql_citta"e vi sarà inserito l'ID della tabella "sql_citta".
Quando si inserisce un nuovo utente nella tabella "sql_agenda", invece di mettere cap, citta e prov è sufficiente mettere il solo ID relativo al record di questi tre campi.

I campi della tabella sql_citta
Field Type Null Key Default Extra
id int NO PRI auto_increment
cap varchar(10) YES
citta varchar(250) YES
prov varchar(10) YES
I campi della tabella sql_agenda
Field Type Null Key Default Extra
id int NO PRI auto_increment
cognome varchar(250) NO
nome varchar(250) NO
indirizzo varchar(250) NO
id_citta int NO
data_nascita date NO
telefono varchar(250) NO

I files .sql che si useranno per la creazione delle tabelle

La creazione delle nuove tabelle non possiamo farlo col metodo visto nella pagina "Duplicare tabella e dati", Ma dovremmo servirci di una Query o dei files .sql.
Queste mostrate qui sotto potrebbero essere i due files .sql necessari alla creazione delle due tabelle.
Per far questo occorre che ci procuriamo due files con estensione .sql adatte a creare le due tabelle che ci occorrono.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
-- phpMyAdmin SQL Dump
-- version 2.10.3
-- http://www.phpmyadmin.net
-- 
-- Host: localhost
-- Generato il: 07 Nov, 2013 at 11:22 PM
-- Versione MySQL: 5.0.51
-- Versione PHP: 5.2.6

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

-- 
-- Database: `MY_DB`
-- 

-- --------------------------------------------------------

-- 
-- Struttura della tabella `sql_citta`
-- 

DROP TABLE IF EXISTS `sql_citta`;
CREATE TABLE IF NOT EXISTS `sql_citta` (
  `id` int(10) NOT NULL auto_increment,
  `cap` varchar(10) NOT NULL,
  `citta` varchar(250) default NULL,
  `prov` varchar(10) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-- phpMyAdmin SQL Dump
-- version 2.10.3
-- http://www.phpmyadmin.net
-- 
-- Host: localhost
-- Generato il: 07 Nov, 2013 at 11:21 PM
-- Versione MySQL: 5.0.51
-- Versione PHP: 5.2.6

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

-- 
-- Database: `MY_DB`
-- 

-- --------------------------------------------------------

-- 
-- Struttura della tabella `sql_agenda`
-- 

DROP TABLE IF EXISTS `sql_agenda`;
CREATE TABLE IF NOT EXISTS `sql_agenda` (
  `id` int(10) NOT NULL auto_increment,
  `cognome` varchar(250) NOT NULL,
  `nome` varchar(250) NOT NULL,
  `indirizzo` varchar(250) NOT NULL,
  `id_citta` int(10) NOT NULL,
  `data_nascita` date NOT NULL,
  `telefono` varchar(250) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Metodi per creazione delle tabelle

Per creare le nuove tabelle di cui necessitiamo possiamo seguire diverse strare di cui queste potrebbero esserne alcune:

  • creazione delle nuove tabelle attraverso il pannello di controllo di phpmyadmin usando i files .sql
  • creazione delle tabelle unsando i files .sql ed un breve script PHP
  • Creazione delle tabelle attraverso delle Query "CREATE TABLE" create ad hoc

Caso 1: creare le tabelle da pannello di controllo di phpmyadmin

Una volta in possesso dei due files .sql possiamo recarci al pannello di controllo di phpmyadmin ed importiamo i due files come indicato in questa immagine.

Caso 2: creare le tabelle con script PHP

Per creare le due tabelle tramite script PHP possiamo usare il codice visibile qui in basso, nel riquadro sottostante.
Questo script inizia, come il solito, con l'inclusione del file db_login.php.
Dal nome della tabella individua il file .sql.
Una volta eseguita la connessione al DB, legge il contenuto el file .sql mettendo tutte le righe del file nella matrice $file_content (riga 13)
Nelle righe seguenti scorre le righe della matrice e, se la riga è valida, ci crea la Query che poi userà alla riga 21
Questo script va usato una volta per ogni tabella si intende creare, quindi, in questo caso, va usato due volte o, quanto meno, andrebbero duplicate le righe che vanno dalla 13 alla 29, cambiando ogni volta il nome della tabella.

Per risparmiare codice e per lasciare lo script così come si trova possiamo agire in questo modo:
Lo script va salvato in un file chiamato "create_table_to_file.php" o con altro nome: in questo caso dobbiamo cambiare anche gli include che si vedono nel riquadro di destra.
Nella pagina che useremo per creare le due tabelle scriveremo le poche righe che si trovano nel riquadro di destra. In questo frammento di codice definiamo le due tabelle e, per ciascuna di esse, eseguiamo un include della pagina che crea la tabella.

Il file create_table_to_file.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
include ('res/db_login.php');
$sqlfile "sql_files/" $table ".sql";
if (!
$link mysql_connect($Host$User$Password)) {
    echo 
mysql_error();
} else {
    if (!
mysql_select_db($DBName)) {
        echo 
mysql_error();
    } else {
        
mysql_set_charset("utf8");
        if( 
mysql_num_rowsmysql_query("SHOW TABLES LIKE '".$table."'"))){
            echo 
"La tabella " $table " esiste nel DB<br />\n";
        } else {
            
$file_content file($sqlfile);
            
$query "";
            
$rec_count 0
            foreach(
$file_content as $sql_line){
                if(
trim($sql_line) != "" && strpos($sql_line"--") === false){
                    
$query .= $sql_line;
                    if (
substr(rtrim($query), -1) == ';'){
                        
$rec_count ++;
                        
$result mysql_query($query);
                        if (!
$result) {
                            echo 
mysql_error() . "<br />\n";
                        }
                        
$query "";
                    }
                }
            }
            echo 
"Tabella " $table " creata correttamente<br />\n";
        }    
    }
}
mysql_close ($link);
?> 

Nella pagina che dovrà creare le tabelle
1
2
3
4
5
6
7
8
<?php
$table_agenda 
"sql_agenda";
$table_citta "sql_citta";
$table $table_agenda;
include (
'create_table_to_file.php');
$table $table_citta;
include (
'create_table_to_file.php');
?>

Caso 3: uso di Query CREATE TABLE per creare le tabelle

Le Query visibili qui sotto hanno bisogno di questi elementi:

  • l'istruzione CREATE TABLE
  • l'indicazione di tutti gli elementi (campi) da inserire nella tabella a cui dobbiamo assegnare:
  • un nome
  • due proprietà:
    • il tipo di dato che dovrà ospitare
    • il valore Null o Not Null
  • per il campo ID abbiamo altre due proprità aggiuntive
    • auto_increment
    • la qualifica di PRIMARY KEY
  • il tipo di ENGINE impostato a MyISAM
  • infine viene indicato il CHARSET e da quale numero inizia l'AUTO_INCREMENT

Detto questo possiamo creare le nostre Query per creare le due tabelle necessarie.

1
2
3
4
5
6
7
8
9
<?php
$Query 
"CREATE TABLE IF NOT EXISTS sql_citta (
  id int(10) NOT NULL auto_increment,
  cap varchar(10) NOT NULL,
  citta varchar(250) default NULL,
  prov varchar(10) NOT NULL,
  PRIMARY KEY  (id)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"
;
?>

1
2
3
4
5
6
7
8
9
10
11
12
<?php
$Query 
"CREATE TABLE IF NOT EXISTS sql_agenda (
  id int(10) NOT NULL auto_increment,
  cognome varchar(250) NOT NULL,
  nome varchar(250) NOT NULL,
  indirizzo varchar(250) NOT NULL,
  id_citta int(10) NOT NULL,
  data_nascita date NOT NULL,
  telefono varchar(250) NOT NULL,
  PRIMARY KEY  (id)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;"

?>

Per eseguire queste due query è sufficiente usare queste poche righe di codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
include ('res/db_login.php');
if (!
$link mysql_connect($Host$User$Password)) {
    echo 
mysql_error() . "<br />\n";
} else {
    if (!
mysql_select_db($DBName)) {
        echo 
mysql_error() . "<br />\n";
    } else {
        
$result mysql_query($Query);
    }
}
mysql_close ($link);
?>

Importazione dei dati: INSERT e subquery

Dopo aver creato le strutture delle due tabelle con uno dei metodi appena visti possiamo pensare di trasferire i dati dalla tabella originale alle due nuove tabelle. Possiamo pensare di farlo manualmente oppure creare due Query speciali che provvedono a trasferire in maniera automatica i dati prelevandoli dalla tabella originale.

La sintassi per eseguire questa operazione si usa questa sintassi:

INSERT INTO tab_destinazione [(elenco campi)]
(SELECT elenco campi from tab_origine)

dove elenco campi indicato nella clausola INSERT è facoltativo se tutti i campi della tab_destinazione coincidono con tutti i campi della tab_origine. Ma se vengono indicati i campi nella clausola INSERT gli stessi campi debbono essere mensionati anche nella clausola SELECT

Questi tipi di Query sono molto delicate ed il buon esito della loro esecuzione dipende da come viene istruita la subquery SELECT. E' per questo motivo che prima di eseguire una Query INSERT è buona norma creare e testare la subquery SELECT.

INSERT e subquery per la tabella sql_citta.

In questa Query:
Si inizia nel modo classico:
INSERT INTO sql_citta (cap, citta, prov)
Nella seconda parte della Query iniziamo a costruire la subquery SELECT
Nella subquery SELECT vengono indicati i campi nello stesso ordine usato nella istruzione INSERT INTO. Viene usata la clausola DISTINCT per selezionare uno solo degli eventuali record duplicati che verrebbero restituini nel recordset ed alla fine viene usata anche la clausola ORDER BY (anche se in questo caso è ininfluente) per ottenere un recordset ordinato da memorizzare nella tabella.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
//    la Query di prova
$Query_test "SELECT DISTINCT cap, citta, prov 
FROM sql_rubrica 
ORDER BY citta
"
;
//    la Query finale
$Query_ins_citta "INSERT INTO sql_citta_2 
(cap, citta, prov) 
SELECT DISTINCT cap, citta, prov 
FROM sql_rubrica 
"
;
?>

Importazione dei dati nella tabella sql_agenda: INSERT e subquery

Ora si può passare alla tabella sql_agenda.
Questa seconda Query è più complessa di quella appena vista. Vediamo ora se riusciamo a spiegarne il senso.
Si inizia la Query alla solita maniera:
INSERT INTO sql_agenda (cognome, nome, indirizzo,........., id_citta)
A questo punto, per prelevare anche l'ID della città da memorizzare nel campo id_citta, dobbiamo creare una SELECT che restituisca nei record del recordset tutti i campi descritti nella istruzione SELECT prelevandoli dalla tabella di origine sql_rubrica e l'ID dalla tabella sql_citta tramite una JOIN tra le due tabelle. Quindi:
Nella istruzione SELECT specifichiamo tutti i campi necessari qualificandoli (un campo qualificato si ha quando davanti al suo nome è presente anche il nome della tabella seguito da un punto).
Per semplificare la scrittura delle istruzioni nella clausola FROM viene dato un alias al nome della tabella sql_rubrica.
Subito dopo la clausola FROM viene impostata la INNER JOIN per creare il collegamento con la seconda tabella. Dopo la JOIN viene specificata la clausola ON per definire la condizione di JOIN.
In questa ultima clausola vengono definite tre condizioni:
dalla tabella sql_citta viene prelevato l'ID solo se c'è corrispondenza tra il cap, la citta e la provincia della tabella sql_citta e della tabella sql_rubrica.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
//    test per verificare se la SELECT funziona
$Query "SELECT sql_rubrica.cognome, sql_rubrica.nome, sql_rubrica.indirizzo, sql_citta.id AS id_citta, sql_rubrica.data_nascita, sql_rubrica.telefono 
FROM sql_rubrica LEFT JOIN sql_citta 
ON sql_rubrica.cap = sql_citta.cap
AND sql_rubrica.citta = sql_citta.citta
AND sql_rubrica.prov = sql_citta.prov
"
;
//    query per copiare i record
$Query_trasf "INSERT INTO sql_agenda (cognome, nome, indirizzo, id_citta, data_nascita, telefono) 
(SELECT sql_rubrica.cognome, sql_rubrica.nome, sql_rubrica.indirizzo, sql_citta.id AS id_citta, sql_rubrica.data_nascita, sql_rubrica.telefono 
FROM sql_rubrica LEFT JOIN sql_citta 
ON sql_rubrica.cap = sql_citta.cap
AND sql_rubrica.citta = sql_citta.citta
AND sql_rubrica.prov = sql_citta.prov)
"
;
?>

Gli effetti delle operazioni compiute

Qui sotto vengono mostrati i contenuti delle tre tabelle su cui abbiamo lavorato.

Questa è la tabella sql_rubrica che abbiamo usato per generare le altre due tabelle. Per comodità, delle tabelle più grandi, mostriamo solo alcuni dei campi ed i primi record e non tutti i campi perchè ovvi.

La tabella sql_rubrica (origine dati)
trovati 101 record
15 record visualizzati
id codice cognome nome indirizzo cap citta prov data_nascita telefono
1 201_parente_000 Migliavacca Luigi VIA P. FIMIANI TRIVIO 35031 Varena AE 2004-01-22 084 41655
2 002_fam_010 Rizzi Carlo VIA SABIN, 34/2 35031 Varena AE 2007-11-22 07 9940508
3 002_fam_020 Liberali Franca VIA DEL TUSCOLANO, 1 67030 Abbadia Lariana AB 2004-02-20 036 348719
4 003_fam_001 Di Maggio Mario TERMINAL CONTENITORI MOLO VII 51021 Ville di Fano RF 2009-05-21 051 18752
5 003_fam_002 Scicchitano Andrea VIA SABIN, 34/2 51021 Ville di Fano RF 1997-01-12 07 74891
6 003_fam_010 Edelvisi Maurizio VIA MATTEO RICCI, 12 51021 Ville di Fano RF 1987-07-02 079 89428
7 003_fam_020 Gerardini Silvano Z.I SAMBUCETO 51021 Ville di Fano RF 2009-08-12 012 164848
8 500_conosc_000 Pasotti Alessio VIA SABIN, 34/2 22050 Correzzana FS 1987-11-14 05 9552713
9 004_fam_001 Calvi Giovanni VIA SABIN, 34/2 53021 Marsiliana AB 1987-07-26 044 5602773
10 004_fam_002 Poggi Giuseppe VIA SABIN, 34/2 67030 Abbadia Lariana AB 1987-01-25 08 0640120
11 004_fam_010 Curti Oreste STRADA MARCHESANE, 43_4 51021 Ville di Fano RF 1988-06-26 027 42781
12 004_fam_021 Borsotti Mirella VIA DEL TUSCOLANO, 1 51021 Ville di Fano RF 1987-07-19 09 379786
13 004_fam_020 Franchinotti Anna VIA BREDINA, 6 67030 Abbadia Lariana AB 2009-05-10 062 8880
14 500_conosc_000 Pischedda Giovanni VIA MATTEO RICCI, 12 22059 Falconara Alta FS 1999-08-08 07 628585
15 004_fam_030 Maini Marilena MACRON TICHON STREET, 27 57020 Borgo S. Dalmazzo BO 2002-03-20 02 6638

Le due tabelle qui sotto sono state valorizzate coi dati prelevati dalla tabella sorgente dei dati. Si può notare che mentre la tabella sql_citta ha i campi cap, citta, prov già presenti nella tabella sorgente, la tabella sql_agenda ha molti dei campi della tabella sorgente ma, invece dei campi cap, citta, prov ha solo un id_citta. Questo campo serve per collegarla alla tabella sql_citta tramite il suo ID.

La tabella sql_citta
trovati 38 record
15 record visualizzati
id cap citta prov
1 35031 AbanoTerme PD
2 23821 Abbadia Lariana LC
3 56011 Agropoli GH
5 06031 Bevagna PG
6 12011 Borgo S. Dalmazzo CN
7 18037 Castel Vittorio IM
8 43050 Cereseto PR
9 44030 Coccanile FE
10 89030 Condofuri RC
12 60013 Corinaldo AN
13 20050 Correzzana MB
14 60015 Falconara Alta AN
15 17010 Giusvalla SV
18 58010 Marsiliana GR
19 55060 Massarosa LU
La tabella sql_agenda
trovati 103 record
15 record visualizzati
id cognome nome indirizzo id_citta data_nascita telefono
1 Migliavacca Luigi VIA P. FIMIANI TRIVIO 21 2004-01-22 084 41655
2 Rizzi Carlo VIA SABIN, 34/2 21 2007-11-22 07 9940508
3 Liberali Franca VIA DEL TUSCOLANO, 1 2 2004-08-20 036 348719
4 Di Maggio Mario TERMINAL CONTENITORI MOLO VII 22 2009-05-21 051 18752
5 Scicchitano Andrea VIA SABIN, 34/2 22 1997-01-12 07 74891
6 Edelvisi Maurizio VIA MATTEO RICCI, 12 22 1987-07-02 079 89428
7 Gerardini Silvano Z.I SAMBUCETO 22 2009-08-12 012 164848
8 Pasotti Alessio VIA SABIN, 34/2 13 1987-11-14 05 9552713
9 Calvi Giovanni VIA SABIN, 34/2 18 1987-07-26 044 5602773
10 Poggi Giuseppe VIA SABIN, 34/2 2 1987-01-25 08 0640120
11 Curti Oreste STRADA MARCHESANE, 43_4 22 1988-06-26 027 42781
12 Borsotti Mirella VIA DEL TUSCOLANO, 1 22 1987-07-19 09 379786
13 Franchinotti Anna VIA BREDINA, 6 2 2009-05-10 062 8880
14 Pischedda Giovanni VIA MATTEO RICCI, 12 14 1999-08-08 07 628585
15 Maini Marilena MACRON TICHON STREET, 27 6 2002-03-20 02 6638

La tabella qui sotto mostra come impiegare le due tabelle appena create per ottenere le informazioni come dalla tabella originale.
Tramite una JOIN preleva i dati da entrambe le tabelle basandosi sui campi id_citta della tabella sql_agenda e id della tabella sql_citta. Sulle JOIN parleremo in sede a parte nel settore delle SELECT. In questa sede la usiamo solo per mostrare quel che possiamo ottenere unendo due tabelle relazionate.
La colonna id_citta che si vede nella tabella, normalmente, negli usi comuni, non viene mostrata. Qui invece ho preferito mostrarla per poter effettuare le comparazioni visive tra le varie tabelle.
Questa tecnica della JOIN verrà mostrata in una delle pagine seguenti, ma qui ne facciamo una anticipazione con questo frammento di codice dove viene usata la Query che esegue la JOIN tra le due tabelle sql_agenda e sql_citta.

Qui di seguito un esempio di Query che usa la tecnica della JOIN tra le due tabelle

1
2
3
4
5
6
7
8
9
10
<?php
$Query_join 
"SELECT sql_agenda.cognome, sql_agenda.nome, sql_agenda.indirizzo, 
sql_citta.id AS id_citta, sql_citta.cap, sql_citta.citta, sql_citta.prov, 
DATE_FORMAT( sql_agenda.data_nascita, '%d-%m-%Y' ) AS nato, 
sql_agenda.telefono 
FROM sql_agenda 
INNER JOIN sql_citta 
ON sql_agenda.id_citta = sql_citta.id
"
;
?>

Lo script usato è quello che viene usato per una qualsiasi Query SELECT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
include ('res/db_login.php');
if (!
$link mysql_connect($Host$User$Password)) {
    echo 
mysql_error() . "<br />\n"
} else {
    if (!
mysql_select_db($DBName)) {
        echo 
mysql_error() . "<br />\n"
    } else {
        
mysql_set_charset("utf8");
        
$result mysql_query($Query);
        
$num_row mysql_num_rows($result);
        
$numfields mysql_num_fields($result);
        
$fields = array();
        for (
$i=0$i $numfields$i++) {
            
$fields[] = mysql_field_name($result$i);
        }
        echo 
$num_row " record letti<br />\n";
        echo 
"<table>\n";        
        echo 
"<tr>\n";
        for (
$i=0$i $numfields$i++) {
            echo 
"<td>" $fields[$i] . "</td>\n";
        }
        echo 
"</tr>\n";
        while (
$row mysql_fetch_array($result)) {
            echo 
"<tr>\n";
            for (
$i=0$i $numfields$i++) {
                echo 
"<td>" $row[$fields[$i]] . "</td>\n";
            }
            echo 
"</tr>\n";
        }
        echo 
"</table>\n";
    }
}
mysql_close ($link);

Il codice appena visto produce una cosa del genere (ovviamente la tabella è ridotta per motivi di spazio).

I dati vengono mostrati usando una JOIN tra la tabella sql_agenda e la tabella sql_citta
trovati 103 record
15 record visualizzati
cognome nome indirizzo id_citta cap citta prov nato telefono
Migliavacca Luigi VIA P. FIMIANI TRIVIO 21 38030 Varena TN 22-01-2004 084 41655
Rizzi Carlo VIA SABIN, 34/2 21 38030 Varena TN 22-11-2007 07 9940508
Liberali Franca VIA DEL TUSCOLANO, 1 2 23821 Abbadia Lariana LC 20-08-2004 036 348719
Di Maggio Mario TERMINAL CONTENITORI MOLO VII 22 67010 Ville di Fano AQ 21-05-2009 051 18752
Scicchitano Andrea VIA SABIN, 34/2 22 67010 Ville di Fano AQ 12-01-1997 07 74891
Edelvisi Maurizio VIA MATTEO RICCI, 12 22 67010 Ville di Fano AQ 02-07-1987 079 89428
Gerardini Silvano Z.I SAMBUCETO 22 67010 Ville di Fano AQ 12-08-2009 012 164848
Pasotti Alessio VIA SABIN, 34/2 13 20050 Correzzana MB 14-11-1987 05 9552713
Calvi Giovanni VIA SABIN, 34/2 18 58010 Marsiliana GR 26-07-1987 044 5602773
Poggi Giuseppe VIA SABIN, 34/2 2 23821 Abbadia Lariana LC 25-01-1987 08 0640120
Curti Oreste STRADA MARCHESANE, 43_4 22 67010 Ville di Fano AQ 26-06-1988 027 42781
Borsotti Mirella VIA DEL TUSCOLANO, 1 22 67010 Ville di Fano AQ 19-07-1987 09 379786
Franchinotti Anna VIA BREDINA, 6 2 23821 Abbadia Lariana LC 10-05-2009 062 8880
Pischedda Giovanni VIA MATTEO RICCI, 12 14 60015 Falconara Alta AN 08-08-1999 07 628585
Maini Marilena MACRON TICHON STREET, 27 6 12011 Borgo S. Dalmazzo CN 20-03-2002 02 6638

 

 



settore tecnico il sito di lorettabweb il Forum di sostegno
il forum il forum il forum