Newsgroup: it.comp.appl.access
Titolo: Denormalizzare database uno a molti per uso statistico, come?

Per un uso statistico avrei la necessità di denormalizzare una database
(file .mdb) che ha tabelle uno a molti, in cui nella tabella detail possono
essere presenti al max 3 record legati alla tabella master. Immaginando di
creare una struttura fissa di un unico record che contiene il record della
tabella master e i max 3 della detail come posso raggiungere questo scopo? I
campi di entrambi le tabelle sono quasi tutti numerici o stringa di piccole
dimensioni.
Ringrazio chi risponde.
Mark

 wrote in message
Z5sE8.58929$zW3.8...@news1.tin.it...


 semplice query a campi incrociati...
Ho già provato ad usare una query a campi incrociati ma non va bene. Eccoti
un esempio:
Tabella UNO
ID | NOME    |
1   | pippo      |
...    ....
Tabella MOLTI
ID | COD1 | COD2 |
1   | 02       | 03        |
1   | 01       | 01        |
2   | 01       | 04        |
3   | 01       | 02        |
3   | 02       | 05        |
quello che vorrei ottenere è un unico record che contiene le informazioni
uno a molti, ad esempio:
Tabella de-normalizzata:
ID | 1COD1 | 1COD2 | 2COD1 | 2COD2 |
1   |  02         |  03        |  01         |  01        |
2   |  01         | 01         |                |              |
3   |  01         |  02        |   02        |   05       |

 3   |  01         |  02        |   02        |   05       |
Che e' appunto cio' che fa una query a campi incrociati.
Avrai provato male.
Sib

 Sib
Ma no scusa, con la query a campi incrociati posso sommare, raggruppare o
ottenere totali che è una cosa diversa da quello che chiedo. Una query a
campi incrociati non potrà mai destrutturare una tabella ma al massimo ti
può facilitarne l'analisi. C'è qualcun'altro che si è imbattuto in questa
problematica?
Ringrazio chi risponde.
Mark

 ha scritto nel messaggio
news:ZZBE8.48370$CN3.1...@news2.tin.it...

L'unico sistema per denormalizzare due tabelle con una relazione di tipo
master-detail (o uno a molti che dir si voglia) è quello di duplicare i dati
della tabella master in tutti i record della nuova tabella (questa
operazione è detta proprio di denormalizzazione). Mi spiego con un esempio
ipotizzando 3 record di dettaglio per ogni record master:
Tabella master Tabella detail
R1|Campo M1|Campo M2|Campo M3| R1|Campo D1|Campo D2|Campo D3|Campo D4|
R2|Campo D1|Campo D2|Campo D3|Campo D4|
R3|Campo D1|Campo D2|Campo D3|Campo D4|
Nuova tabella denormalizzata
R1|Campo M1|Campo M2|Campo M3|Campo D1|Campo D2|Campo D3|Campo D4|
R2|Campo M1|Campo M2|Campo M3|Campo D1|Campo D2|Campo D3|Campo D4|
R3|Campo M1|Campo M2|Campo M3|Campo D1|Campo D2|Campo D3|Campo D4|
Questo è quanto.
Se poi la tabella così ottenuta è di dimensioni molto grandi puoi spostare i
campi che non contengono dati numerici, detti dimensioni in una serie di
piccole tabelle collegate a quella principale tramite una serie di relazioni
ed ottenere così quello che viene definito nel campo del data warehousing
uno star-schema molto prestante per quanto riguarda le interrogazioni che
coinvolgono grosse quantità di dati.
Spero di esssere stato chiaro, se hai bisogno sono sempre qui.
Roberto Pasqualini

 ha scritto nel messaggio
news:ZatE8.59194$zW3.8...@news1.tin.it...

Se la tabella UNO ha la seguente struttura:
ID            Contatore e chiave primaria
NOME    Testo
ecc. ecc.
Se la tabella MOLTI ha la seguente struttura:
IDMolti    Contatore e chiave primaria
ID            Numerico
COD1      Testo
COD2      Testo
ecc. ecc.
Se le tabelle UNO e MOLTI sono in relazione uno-a-molti in base ai campi ID.
Se la tabella che deve contenere il risultato dell'elaborazione si chiama
Denormalizzata ed ha la seguente struttura:
ID                Numerico e chiave primaria
C1COD1    Testo
C1COD2    Testo
C2COD1    Testo
C2COD2    Testo
C3COD1    Testo
C3COD2    Testo
Puoi ottenere ciò che ti serve con il seguente codice VBA che fa riferimento
alle librerie DAO, che comunque (anche se usi A2000 o A2002)dovranno far
parte dei riferimenti del tuo database:
Dim rstUNO As Recordset
Dim rstMOLTI As Recordset
Dim rstDen As Recordset
Dim Dep1COD1 As Variant, Dep1COD2 As Variant
Dim Dep2COD1 As Variant, Dep2COD2 As Variant
Dim Dep3COD1 As Variant, Dep3COD2 As Variant
Set rstUNO = CurrentDb.OpenRecordset("UNO")
Set rstMOLTI = CurrentDb.OpenRecordset("MOLTI")
Set rstDen = CurrentDb.OpenRecordset("Denormalizzata")
rstUNO.MoveFirst
Do Until rstUNO.EOF
    Dep1COD1 = Null
    Dep1COD2 = Null
    Dep2COD1 = Null
    Dep2COD2 = Null
    Dep3COD1 = Null
    Dep3COD2 = Null
    rstDen.AddNew
    rstDen!ID = rstUNO!ID
    rstMOLTI.MoveFirst
    Do Until rstMOLTI.EOF
        If rstMOLTI!ID = rstUNO!ID Then
            If IsNull(Dep1COD1) Then
                Dep1COD1 = rstMOLTI!COD1
                Dep1COD2 = rstMOLTI!COD2
            Else
                If IsNull(Dep2COD1) Then
                    Dep2COD1 = rstMOLTI!COD1
                    Dep2COD2 = rstMOLTI!COD2
                Else
                    Dep3COD1 = rstMOLTI!COD1
                    Dep3COD2 = rstMOLTI!COD2
                End If
            End If
        End If
        rstMOLTI.MoveNext
    Loop
    rstDen!C1COD1 = Dep1COD1
    rstDen!C1COD2 = Dep1COD2
    rstDen!C2COD1 = Dep2COD1
    rstDen!C2COD2 = Dep2COD2
    rstDen!C3COD1 = Dep3COD1
    rstDen!C3COD2 = Dep3COD2
    rstDen.Update
    rstUNO.MoveNext
Loop
Set rstUNO = Nothing
Set rstMOLTI = Nothing
Set rstDen = Nothing
Visto la sudata che ho fatto a scrivere il codice VBA, spero che era ciò che
ti serviva. :-)
Se non usi A97, ricordati i riferimenti alle librerie DAO.
--
Roberto
---------------------------------------------
il Sito Comune di it.comp.appl.access:
http://www.sitocomune.com
---------------------------------------------

 .........
La soluzione che hai trovato funziona benissimo era proprio quello che
cercavo. Ho usato un file di Access XP (DAO 3.6). Una domanda ancora,
(rispondimi solo se ne hai voglia:) ) se il numero dei record nella tabella
detail fosse indeterminato? Ti ringrazio comunque per la risposta data.
Marco
P.S.
Sarebbe utile sul sito comune se s'inserisse una piccola sezione dedicata
alle tecniche di data warehousing.

 Roberto Pasqualini
Hai proprio centrato il problema. Sto' cercando di creare delle tabelle di
data warehousing e non sono a conoscenza di quali tecniche usare. L'ottimo
"Roberto da casa" ha individuato il problema che avevo, questo mi consente
di usare una tabella access destrutturata (o denormalizzata?) con un
programma di statistica che si chiama SPSS. La soluzione che mi hai proposto
riesco ad ottenerla cambiando il tipo di join in una query sulle due tabelle
(master-detail) però così ottengo una tabella con più righe (record) per
ogni record master. E' comunque una soluzione che può tornare utile per
altre situazioni. Mi daresti qualche informazione in più sullo star-schema?
Se hai qualche piccolo esempio didattico in .mdb vale più di mille parole.
Grazie ancora e ciao.


 alle tecniche di data warehousing.
Puň darsi che tu abbia ragione, ma non conosco affatto tali tecniche.


 può facilitarne l'analisi.
A volte si legge frettolosamente e sfugge qualcosa.
Il tuo commento sul "qualcunaltro" che volesse rispondere mi e' sembrato
fuori posto.
Ad ogni modo se la tua tabella lato molti si chiama "Tabella1Slave" composta
da
ID chiave primaria
IDTab1 Campo collegato alla tabella principale
DatiVariA
DatiVariB
e ammesso che tu abbia una "profondita'" di 2 record di dettaglio puoi
creare queste tre query che lavorano in cascata.
Per aumentare la profondita' devi creare una query TerziID con criteri
analoghi a quelli usati nelle prime due e modificare di conseguenza la query
"Denormalizza".
Query "PrimiID"
SELECT Min(Tabella1Slave.ID) AS MinDiID, Tabella1Slave.IDTab1
FROM Tabella1Slave
GROUP BY Tabella1Slave.IDTab1;
Query "SecondiID"
SELECT DISTINCTROW Min(Tabella1Slave.ID) AS MinDiID1, Tabella1Slave.IDTab1
FROM Tabella1Slave LEFT JOIN PrimiID ON Tabella1Slave.ID = PrimiID.MinDiID
GROUP BY Tabella1Slave.IDTab1, PrimiID.MinDiID
HAVING (((PrimiID.MinDiID) Is Null));
Query "Denormalizza"
SELECT Tabella1Slave.ID, Tabella1Slave.IDTab1, Tabella1Slave.DatiVariA,
Tabella1Slave.DatiVariB, Tabella1Slave_1.DatiVariA,
Tabella1Slave_1.DatiVariB
FROM ((PrimiID LEFT JOIN SecondiID ON PrimiID.IDTab1 = SecondiID.IDTab1)
INNER JOIN Tabella1Slave ON PrimiID.MinDiID = Tabella1Slave.ID) LEFT JOIN
Tabella1Slave AS Tabella1Slave_1 ON SecondiID.MinDiID1 = Tabella1Slave_1.ID;
Sib

 detail fosse indeterminato?
Indeterminato e' una parola grossa.
anche perche' una tabella o query di access contiene al massimo 255 campi
(che sono gia' molti)
tutt'al piu' puoi prevedere un certo numero di campi in partenza (20-30 o
anche piu')
Sib

 Può darsi che tu abbia ragione, ma non conosco affatto tali tecniche.
http://ipvaimed1.unipv.it/references/oracle8.1.6/doc/oracle8i_816/server.816
/a76994/toc.htm
Tutto sommato e' un semplice problema d'approccio.
Per quanto mi riguarda non ho mai sentito la necessita' di denormalizzare
per aumentare le prestazioni dei report di analisi dei dati.
Certamente i miei clienti non sono delle multinazionali e quindi i dati da
analizzare non sono di dimensioni enormi (raramente sopra i 500Mb nel file
mdb). D'altro canto se la mole dei dati fosse superiore suggerirei l'uso di
altri motori database (SQL o altro) il che provocherebbe un aumento delle
prestazioni tale da rendere inutile utilizzare data warehousing.
A questo punto diventa una questione di gusti.
Io c'ho la passione della normalizzazione che cce' vo' fa'.
Sib

 fuori posto.
Nessun tono polemico, anzi ti ringrazio per avermi postato una soluzione
alternativa. Bye
Mark

 anche piu')
In effetti quello che volevo dire e se sulla tabella detail ci sono record
in numero non fisso. So' di questo limite di Access sul numero dei campi, in
parte lo bypasso usando Excel. E' per una statistica medica in cui è il caso
di usare una struttura dei records de-normalizzata. Il programma di
statistica è SPSS. Come database uso Interbase (SQL) e per generare la
statistica produco dei file .mdb via ADO. La mole dei dati comunque non è
molto grossa. Grazie ancora. Bye
Mark

 molto grossa. Grazie ancora. Bye
Il problema che mi pongo e': che significato hanno tabelle di analisi con
centinaia di campi?
La mente umana non puo' seguire tutto insieme e d'altro canto i database
(come access) sono stati creati per analizzare i dati e presentarci delle
statistiche comprensibili (e quindi con un numero di campi massimo di poche
decine).
Ho la sensazione che usi uno strumento di analisi come access quale tramite
per passare i dati di cui disponi ad un altro strumento di analisi. E' ovvio
quindi che qualunque soluzione in questo senso risultera' macchinosa.
L'uso di access in questo caso e' pura opzione.
Ciao
Sib

 L'uso di access in questo caso e' pura opzione.
Ovviamente il mio è un caso non frequente. Ti faccio un esempio pratico, la
raccolta dei dati di un paziente aorto-coronarico ha non meno di circa 220
tipi di informazione diverse. A queste si aggiungono interventi precedenti e
follow-up. Ora per un certo tipo di statistica medica queste informazioni
devono essere elaborate con lo schema de-normalizzato anche se si avrà un
record con centinaia di campi. Ci penserà il programma di statistica a
trovare tutto quello serve. Access diventa veramente comodo in quanto, se
usato in locale, permette di costruire in maniera molto veloce le tabelle
che interessano (in questo la flessibilità di Access è innegabile) anche con
ad esempio circa 200.000 record. In più Access ha il vantaggio di poter
usato anche da operatori non esperti d'informatica. Comunque ti ripeto è
solo un caso nella stragrande maggioranza delle volte non è necessario
attuare questi procedimenti particolari. Bye
Marco

 follow-up. Ora per un certo tipo di statistica medica queste informazioni
cut
Se non superi i 255 campi puoi usare una tabella costruita dinamicamente o
una query ricorsiva migliorando quella che ti ho suggerito.
Puoi comunque usare un report che peschi i risultati da tutti i controlli
che vuoi.
In pratica questo programma di statistica fa proprio calcoli cosi' complessi
e sofisticati da essere cosi' difficili da rifare?
Sib

 e sofisticati da essere cosi' difficili da rifare?
Hai qualche esempio a cui posso riferirmi? Il programma è SPSS credo che sia
leader nella categoria (costa pure un sacco di soldi) e la statistica in
questione è si complessa e sofisticata prettamente medico-scientifica. Bye
Marco

 ha scritto nel messaggio

Esempi non ne ho.
Comunque da quanto ho potuto vedere sul loro sito (
www.spss.it
) si tratta di
un gruppo di sviluppatori specializzati in calcoli statistici che, con ogni
probabilita' hanno realizzato dei pacchetti preconfezionati che vanno bene
per alcune categorie di utilizzi.
Pero' se leggi tra le righe ti rendi conto che ai loro clienti piu' grossi
(wind) hanno dato dei pacchetti personalizzati. Questo riporta la questione
alla sua base e cioe': il problema non e' mai la realizzazione del calcolo
sul pc ma la sua elaborazione sulla carta. Se i tuoi clienti hanno le idee
chiare su quale debba essere il calcolo da fare non c'e' nulla che possa
impedirti di sviluppare la soluzione. Se i tuoi clienti sono abituati ad
avere una scatola buia dove buttano dentro dei numeri e ne escono altri
senza sapere come e perche' allora avrai vita dura.
Ciao
Sib