Come creare una relazione tra 2 record di una medesima tabella

di il
34 risposte

Come creare una relazione tra 2 record di una medesima tabella

Salve a tutti, ho un dubbio e non so come andare avanti. Avrei necessità di creare una relazione e tra 2 record di una tabella ma non capisco come fare. Faccio un esempio pratico...

Ho una tabella access con i dati anagrafici delle persone. Vorrei costruire un'altra tabella che associ un tipo di relazione tra 2 persone. Esempio marco e paolo sono due persone( 2 record) della prima tabella e la relazione che c'è tra loro è "marco è il babbo di paolo". Come realizzo questa cosa, nel senso come creo la struttura delle relazioni in questo caso?

34 Risposte

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    La prima tabella si chiama Persone: OK.
    La seconda tabella la chiamerai Parentele con i seguenti campi:
    IDParentela (PK)
    IDPersona1 (FK)
    GradoParente1 (qui ci scrivi per esempio padre)
    IDPersona2 (FK)
    GradoParente2 (qui ci scrivi per esempio figlio)

    Crei 2 relazioni:
    Persone.IDPersona uno-a-molti Parentele.IDPersona1
    Persone.IDPersona uno-a-molti Parentele.IDPersona2

    Noterai che Access creerà automaticamente una tabella Persone_1 (non ho mai capito perchè...così è).

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    Quello che ti ha esposto Osvaldo va quasi bene, manca solo una seconda istanza della tabella Persone... in cui la Pk deve andare su IdPersona2

    In sostanza essendo la tabella Persone una tabella di anagrafiche non avrai 2 tabelle separate, quindi l'istanza principale relaziona IdPersona1 e la seconda istanza IdPersona2

    In un diagramma ER devi quindi trascinare 2 volte la tabella Persone.

    Fin qui tutto semplice....ma ora viene il difficile... questo è un sistema gerarchico che potenzialmente può avere livelli infiniti, significa che non saranno facilmente gestibili con normali metodi di Query in quanto potrai arrivare solo al 1° massimo 2° livello ma se c'è ne fossero di più capisci anche tu che prevedere query di query di query sarebbe strutturalmente bloccante.

    Per questo le strutture gerarchiche, almeno con access che non ha un TSQL, vanno gestite principalmente con dei recordset in funzioni ricorsive.

    Non è affatto banale ma nemmeno impossibile, diciamo che se sei digiuno di VBA serve un bel passo avanti.

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    CREATE TABLE nominativi (
     nomeId INTEGER PRIMARY KEY,
     componente TEXT NOT NULL,
     appellativo text NOT NULL,
     parenela integer NOT NULL
    );
    -- insert
    INSERT INTO nominativi VALUES (0001, 'topolino', 'padre', 0001);
    INSERT INTO nominativi VALUES (0002, 'minnie', 'madre', 0001);
    INSERT INTO nominativi VALUES (0003, 'topolina', 'figlio', 0001);
    INSERT INTO nominativi VALUES (0004, 'pippo', 'figlio', 0001);
    INSERT INTO nominativi VALUES (0005, 'pluto', 'figlio', 0002);
    -- fetch 
    SELECT * FROM nominativi as capofamiglia where appellativo='padre'; //tabella master
    SELECT * FROM nominativi as parenti where appellativo='madre' or appellativo='figlio'; // tabella detail

    risultati:

    tabella master capofamiglia
    +--------+------------+-------------+----------+
    | nomeId | componente | appellativo | parenela |
    +--------+------------+-------------+----------+
    |      1 | topolino   | padre       |        1 |
    +--------+------------+-------------+----------+
    
    
    tabella detail parenti
    +--------+------------+-------------+----------+
    | nomeId | componente | appellativo | parenela |
    +--------+------------+-------------+----------+
    |      2 | minnie     | madre       |        1 |
    |      3 | topolina   | figlio      |        1 |
    |      4 | pippo      | figlio      |        1 |
    |      5 | pluto      | figlio      |        2 |
    +--------+------------+-------------+----------+

    impostando la relazione master nomeId con detail parentela ottieni per ogni capofamiglia i parenti collegati.

    ovviamente inserimento, modifica ed eliminazione vanno gestiti da codice.

    alcune considerazioni:

    capofamiglia può essere estrapolata where nomeid=parentela

    hai la tabella di tutti i capofamiglia

    nella tabella detail, visto che fa capo alla stessa tabella nominativi, è stata incorporata la relazione m a m

    la tabella intermedia sarebbe formata di campi nomeId e parentela che a sua volta legherebbe il parente al capofamiglia

    tabella master capofamiglia
    +--------+------------+-------------+----------+
    | nomeId | componente | appellativo | parenela |
    +--------+------------+-------------+----------+
    |      1 | topolino   | padre       |        1 |
    +--------+------------+-------------+----------+
    
    tabella intermedia
    +--------+----------+
    | nomeId | parenela |
    +--------+----------+
    |      2 |        1 |
    |      3 |        1 |
    |      4 |        1 |
    |      5 |        2 |
    +--------+----------+
    
    tabella detail parenti
    +--------+------------+-------------+
    | nomeId | componente | appellativo |
    +--------+------------+-------------+
    |      2 | minnie     | madre       |
    |      3 | topolina   | figlio      |
    |      4 | pippo      | figlio      |
    |      5 | pluto      | figlio      |
    +--------+------------+-------------+
  • Re: Come creare una relazione tra 2 record di una medesima tabella

    12/01/2025 - @Alex ha scritto:

    Quello che ti ha esposto Osvaldo va quasi bene, manca solo una seconda istanza della tabella Persone... in cui la Pk deve andare su IdPersona2

    In sostanza essendo la tabella Persone una tabella di anagrafiche non avrai 2 tabelle separate, quindi l'istanza principale relaziona IdPersona1 e la seconda istanza IdPersona2

    In un diagramma ER devi quindi trascinare 2 volte la tabella Persone.

    Fin qui tutto semplice....ma ora viene il difficile... questo è un sistema gerarchico che potenzialmente può avere livelli infiniti, significa che non saranno facilmente gestibili con normali metodi di Query in quanto potrai arrivare solo al 1° massimo 2° livello ma se c'è ne fossero di più capisci anche tu che prevedere query di query di query sarebbe strutturalmente bloccante.

    Per questo le strutture gerarchiche, almeno con access che non ha un TSQL, vanno gestite principalmente con dei recordset in funzioni ricorsive.

    Non è affatto banale ma nemmeno impossibile, diciamo che se sei digiuno di VBA serve un bel passo avanti.

    io mi accontenterei anche di arrivare al 1° Livello che è quello che mi serve.

    Ho provato a fare come suggerito @OsvaldoLaviosa ma non ne vengo a campo. 

    Per completezza posto cosa ho fatto, nella speranza di poter trovare qualche risposta ma credo che la stessa vada oltre il mio livello di conoscenza di access e di DB in generale.

    Tab. delle persone

    Tab. Relazioni

    Strumenti DB - Relazioni

    Struttura Query

    ed infine la risposta se faccio girare la query...in pratica la query non restituisce niente.

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    Uhm... 

    ma tu hai compilato i campi della tabella relazioneT?

    il primo campo ha come valore il capofamiglia, il secondo un componente

    così fino all'ultimo componente escluso il capofamiglia

    ti ritrovi con

    iduser1    iduser2

    1                 2

    1                3

    1               N

    2               7

    2               8

    2              M

    ecc...

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    15/01/2025 - sihsandrea ha scritto:

    Uhm... 

    ma tu hai compilato i campi della tabella relazioneT?

    Ciao, si ho compilato la tabella relazioniT. 

    Non ho capito cosa mi sta dicendo.

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    16/01/2025 - alexsgv ha scritto:

    Non ho capito cosa mi sta dicendo.

    Puoi mostrare i primi 10 record della tabella relazioneT?

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    16/01/2025 - sihsandrea ha scritto:

    16/01/2025 - alexsgv ha scritto:

    Non ho capito cosa mi sta dicendo.

    Puoi mostrare i primi 10 record della tabella relazioneT?

    Ciao, certo. Ti metto uno screen del post sopra dove ci sono entrambe le tabelle.

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    A patto che la tabella detail sia indicizzata per user1, in base ai dati che vedo:

    se lato master selezioni mario bianchi lato detail vedi elencati 

    - paolo rossi amico

    - sandra verdi cugina

    se lato master selezioni sandra verdi lato detail vedi elencati

    - mario bianchi collega

    come se mario bianchi sia cugino di sandra verdi ma sandra verdi non è cugina di mario bianchi...

    allo stesso modo sandra è collega di mario ma mario non è collega di sandra...

    e paolo rossi non ha amici, cugini e colleghi quando in realtà è amico di mario bianchi.

    non puoi creare più relazioni incrociate che attinge ad una sola tabella con una sola tabella relazionale (perdona il gioco di parole).

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    Mi permetto di segnalare una ulteriore possibile criticita': le relazioni indicate sopra sono tutte "commutative" ovvero in caso di ricerca di un IDUser in entrambi i campi IDUser1 o IDUser2 puoi ritrovare il tipo di relazione.

    Il problema potrebbe essere se utilizzi relazioni di tipo "Padre", oppure "figlio", "nonno": allora in questo caso la cosa si complica: e' chiaro che se IDuser1 e' padre di IDuser2 non puo' essere vero il contrario... Per cui serve attenzione nell'inserimento dati e nell'eventuale successiva interrogazione.

    Poi mi domando: con una query come hai indicato sopra: che tipo di dati Ti aspetti di ricevere? E' ovvio che non restituisca nulla: mancano i parametri di ricerca ed inoltre compare due volte il campo Nome della prima tabella...

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    Pienamente d'accordo con le considerazioni di @Mailman

    quando progetti un database parti dal modello concettuale (er)

    e solo dopo che hai chiaro le relazioni e le entità converti il modello er in uno schema logico

    nello schema logico che hai progettato c'è troppa ambiguità

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    16/01/2025 - Mailman ha scritto:

    Mi permetto di segnalare una ulteriore possibile criticita': le relazioni indicate sopra sono tutte "commutative" ovvero in caso di ricerca di un IDUser in entrambi i campi IDUser1 o IDUser2 puoi ritrovare il tipo di relazione.

    Il problema potrebbe essere se utilizzi relazioni di tipo "Padre", oppure "figlio", "nonno": allora in questo caso la cosa si complica: e' chiaro che se IDuser1 e' padre di IDuser2 non puo' essere vero il contrario... Per cui serve attenzione nell'inserimento dati e nell'eventuale successiva interrogazione.

    Poi mi domando: con una query come hai indicato sopra: che tipo di dati Ti aspetti di ricevere? E' ovvio che non restituisca nulla: mancano i parametri di ricerca ed inoltre compare due volte il campo Nome della prima tabella...

    La relazione "NONNO" è fondamentalmente un modo per non gestire in modo ricorsivo le relazioni gerarchiche quando sono limitati, in questo caso a 2 Livelli, perchè il modo corretto sarebbe gestire le relazioni con salti da 1Livello, usando le ricorsioni, esattamente come fa il TreeView.

    Immaginiamo di gestire salti Multilivello... Bisnonno, Trisnonno ecc, dove ci fermiamo..., questi sono solo termini convenzionali per definire relazioni di 2°-3° o 4° Livello ma non è tecnicamente di buon senso.

    La relazione "NONNO" quindi non dovrebbe esistere perchè di livello 2 e scomponibile gerarchicamente in 2 Relazioni di livello 1, esiste pertanto Padre e Padre del Padre, ovvero 2 salti di 1 livello che sembra meno semplice ma invito a riflettere....

    Questo infatti, l'uso di "NONNO" intendo, è ragionevolmente fattibile, ma obbliga ad inserire un record in più... perchè costringe a definire sia la relazione Nipote-Nonno, che 2 Relazioni Figlio-Padre, altrimenti non potresti tracciare tutte le parentele, mentre usando una normale relazione basata su 1 salto di Livello, che genera ricorsione, bastano 2 Relazioni definite, ovvero Padre-Figlio e Padre-Figlio, automaticamente il 2° Livello di Padre è il Nonno e mantieni la gerarchia completa.

    A---(padre)--> (B)
    B---(padre)--> (C)
    Questo chiarisce con solo 2 inserimenti che C è in relazione livello 2 con A, convenzionalmente Nipote-Nonno
    
    Usando Nonno è indiscutibile che la relazione Nonno sia superflua ma...:
    A---(Nipote)-->(C)	(relazione superflua, le 2 relazioni sotto già contengono questo legame)
    A---(padre)--> (B)
    B---(padre)--> (C)
    

    Provate ad esempio a pensare come rappresentare in un TreeView la relazione Nonno ed anche la relazione Padre-Figlio, vi trovereste con nodi inutili perchè il Nipote verrebbe rappresentato sotto Nonno come Nipote e sotto Figlio del Figlio... non è proprio il massimo, mentre è estremamente lineare esplodere il Nonno trovarci i Figli ed esplodere i Figli e trovarci i Figli(Nipoti del Nonno per definizione).

    Ciò detto come spiegato all'inizio ma comprendo non siano concetti facili per tutti, l'estrazione di Query con Relazioni Multilivello non è gestibile, se non ingessando il sistema... finchè parliamo di Padre Figlio senza una vera cerarchia MultiLivello va bene, ma già dal 2° Livello io abbandonerei andando sulla ricorsione.

    Aggiungo che le relazioni inserite nel ER non sono corrette si aggiunge la seconda istanza della Tabella Anagrafica e si collega la PK della 2° istanza alla FK di Relazione della Tabella Relazioni, se non solo per chiarimento grafico e concettuale.

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    Salve a tutti,

    girando un pò in rete ho trovato questa possibile soluzione ma c'è ancora qualcosa che non funiona.

    ho creato 2 query per arrivare al risultato che volevo e se lancio la query forzando il criterio ottengo quello che voglio ma se poi metto tutto su una maschera non visualizza i nomi. Metto quello che ho fatto per far capire.

    Tabella delle persone:

    Tabella Relazioni:

    La prima query per associare la relazione "utente 1 ha questa relazione":

    La query eseguita:

    La seconda query:

    La seconda query eseguita:

    Fino a qui tutto ok.

    Quando creo la maschera con la relativa sotto maschera iniziano i problemi:

    come campo di associazione ho usato IDPersonaRel_1

    ho provato anche a far giare la query forzando il criterio del campo IDPersonaRel_1 e sembra funzionare

    Non capisco perchè non mi mostra i nomi nella sotto maschera quando la associo nella maschera principale.

    se la apro da sola sembra funzionare.

    Entrambe le maschere prendono i dati dalla seconda query. Ma ho già provato associando la maschera principale alla tabella PERSONE e la satto maschera alla seconda query. Solito risultato.

    Sto smattando, cosa sbaglio?

    Ciccio

  • Re: Come creare una relazione tra 2 record di una medesima tabella

    Uhm.... Avevi chiesto di relazionare due record della stessa tabella ma a te serve una struttura ad albero.

Devi accedere o registrarti per scrivere nel forum
34 risposte