• User Attivo

    Informazioni INNER JOIN

    Buongiorno a tutti,

    forse è una domanda stupida ma ve la faccio lo stesso,

    è possibile fare un INNER JOIN tra una sola tabella?

    vorrei relazionare alcune righe con altre della stessa tabella con l'id.

    ho la riga "bmw", e nella stessa tabella ho la riga "auto",

    "bmw" vorrei relazionarlo con "auto" tramite id,

    tutte le righe hanno una colonna dedicata per le relazioni.

    spero di essermi spiegato

    buona serata e buon week end


  • Moderatore

    Ciao enricocarli,
    puoi fare un self join in questo modo.
    Immagina di avere una tabella *things *con cose (thing), un codice *id *per identificare le cose e una colonna *rel *per le relazioni tra le cose:

    id thing rel
    1 - auto - 0
    2 - moto - 0
    3 - smartphone - 0
    4 - tv - 0
    5 - giornale - 0
    6 - Bmw - 1
    7 - Alfa Romeo - 1
    8 - Corriere della Sera - 5
    9 - iPhone 6 - 3
    10 - Il Mattino - 5
    11 - Toyota - 1
    12 - Kawasaki - 2

    Nella riga id=6 BMW è in relazione con 1 perché BMW è un'automobile e id=1 è appunto l'id di auto. Così per la riga id=7 di Alfa Romeo e per tutte le altre. Quando rel=0 significa che quella cosa (thing) è in relazione con se stessa.

    Se vuoi ottenere con una query le righe in cui compaiono le coppie del tipo (BMW, auto) e (Corriere della Sera, giornale), ovvero coppie del tipo (thing, thing) in relazione tra loro, puoi scrivere una query così:

    
    SELECT a.thing as cosa, b.thing as categoria FROM things a, things b WHERE a.rel = b.id
    
    

    Nella query sopra per semplicità ho immaginato che la seconda colonna funga da categoria per la prima, ma è soltanto un'interpretazione.
    Il risultato della query sopra è:

    cosa categoria
    Bmw - auto
    Alfa Romeo - auto
    Corriere della Sera - giornale
    iPhone 6 - smartphone
    Il Mattino - giornale
    Toyota - auto
    Kawasaki - moto

    Per mettere in relazione una cosa con più cose la questione si complica. Per fare un esempio, la seguente riga:

    cosa categoria
    Honda - 1, 2

    sarebbe più facile da trattare se fosse scritta così:

    cosa categoria
    Honda - 1
    Honda - 2


  • User Attivo

    ciao FDA,

    intanto grazie per la risposta, interessante il SELF JOIN, non lo conoscevo.

    Però in effetti in questa tabella "things" il record BMW deve essere "Auto" ma anche "Moto".

    Per cui se non sbaglio devo fare una tabella di relazione molti a molti.

    Giusto?

    grazie mille
    buona serata
    ciao!


  • Moderatore

    Ciao enricocarli,
    le due tabelle per creare la relazione uno a molti, oppure le tre tabelle per creare quella molti a molti, sono le soluzioni standard.
    Se però hai una tabella come nell'esempio sopra e non vuoi/puoi aggiungere tabelle e relazioni, allora puoi creare una query con il self join.

    Es. se BMW è anche moto allora devi avere una tredicesima riga così:
    id thing rel
    13 - BMW - 2

    Con questa tredicesima riga la SELECT sopra produrrebbe un'ottava riga:

    cosa categoria
    Bmw - moto

    Ciao! 🙂


  • User Attivo

    si però così facendo ho 2 volte BMW, non va bene giusto?
    non c'è qualche regola che dice che non si devono ripetere i dati?

    ciao e grazie mille per l'aiuto!


  • Moderatore

    Al contrario, è giusto mostrare BMW due volte perché in questa query l'unicità della riga è nella coppia "cosa, categoria" e infatti "Bmw, moto" è un'informazione diversa da "Bmw, auto".
    Sopra hai scritto:

    tutte le righe hanno una colonna dedicata per le relazioni.
    Se una cosa (es. Bmw) può essere in relazione con più di una cosa (es. auto, moto) allora è giusto avere due righe.

    Il caso dei dati ripetuti si avrebbe se avessimo una ulteriore riga (la quattordicesima) così:

    id thing rel
    14 - BMW - 1

    La SELECT sopra allora produrrebbe:

    cosa categoria
    Bmw - auto
    Alfa Romeo - auto
    Corriere della Sera - giornale
    iPhone 6 - smartphone
    Il Mattino - giornale
    Toyota - auto
    Kawasaki - moto
    Bmw - moto
    Bmw - auto

    e quindi si avrebbero due righe uguali (la prima e la nona).
    Per evitare righe uguali si può usare la clausola DISTINCT:

    
    SELECT DISTINCT a.thing as cosa, b.thing as categoria FROM things a, things b WHERE a.rel = b.id