Mysql
 sql >> Database >  >> RDS >> Mysql

SQL - Unisci a sinistra 2 chiavi esterne a 1 chiave primaria

Vedo spesso persone che lottano con l'idea di unire una tabella a se stessa o più volte nella stessa query (come se fosse qui). Una volta padroneggiata, è un'ottima tecnica da usare su tavoli che hanno molte relazioni tra le file (come un elenco di squadre che devono affrontarsi!). Come altri hanno sottolineato, è necessario utilizzare due inner join s per ottenere ciò:

select
    *
from
    games g
    inner join teams t1 on
        g.teamid1 = t1.teamid
    inner join teams t2 on
        g.teamid2 = t2.teamid

Quindi, se i tuoi games la tabella si presenta così:

GameID    TeamID1    TeamID2
----------------------------
     1          1          3
     2          4          2
     3          2          1

Otterrai il set di risultati di:

g.GameID    g.TeamID1    g.TeamID2    t1.TeamID    t1.Name    t2.TeamID    t2.Name
----------------------------------------------------------------------------------
       1            1            3            1    Lions              3    Bears
       2            4            2            4    Oh My              2    Tigers
       3            2            1            2    Tigers             1    Lions

Ovviamente, alias queste colonne in select dichiarazione, se fossi in me, per l'usabilità:

select
    g.GameID,
    t1.Name as Team1,
    t2.Name as Team2
from
    ...

In questo modo, le colonne possono essere denominate in modo appropriato, invece di avere il t1 e t2 le colonne condividono gli stessi nomi.

Ora, per risolvere la confusione su ciò che un left join è. Vedi, un left join prenderà tutte le righe dalla prima tabella (o sinistra), quindi abbinerà tutte le righe nella condizione di join alla seconda tabella (o destra). Per qualsiasi riga della tabella di sinistra, otterrai null in tutte le colonne a right tabella.

Approfondindo un esempio, supponiamo che qualcuno abbia inserito un null per TeamID2 su una delle righe per qualsiasi motivo. Diciamo anche che un team di TeamID 4 esisteva, ma non esiste più.

GameID    TeamID1    TeamID2
----------------------------
     1          1          3
     2          4          2
     3          1       null

Ora, diamo un'occhiata a ciò che un left join sarebbe in termini di query:

select
    *
from
    games g
    left join teams t1 on
        g.teamid1 = t1.teamid
    left join teams t2 on
        g.teamid2 = t2.teamid

Logicamente, questo prenderà tutti i nostri games , quindi abbinali ai rispettivi teams . Tuttavia, se un TeamID non esiste, otterremo null S. Sembrerà così:

g.GameID    g.TeamID1    g.TeamID2    t1.TeamID    t1.Name    t2.TeamID    t2.Name
----------------------------------------------------------------------------------
       1            1            3            1    Lions              3    Bears
       2            4            2         null    null               2    Tigers
       3            1         null            1    Lions           null    null

Pertanto, un left join sarà solo essere necessario se una squadra è facoltativa.

Nel tuo caso, utilizzerai un inner join per unirti a un tavolo più volte. Questa è una pratica molto comune ed è piuttosto utile. Evita alcune delle insidie ​​delle sottoquery (soprattutto su MySQL), consentendoti al contempo di prelevare dati dalla tabella per confronti intratable. Ciò è particolarmente utile quando si cerca di trovare l'ordine di qualcosa o le righe correlate.

Ad ogni modo, spero che questa risposta molto sconclusionata aiuti qualcuno da qualche parte.