Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

SQL - Left join 2 chaves estrangeiras para 1 chave primária


Muitas vezes vejo pessoas lutando com a ideia de unir uma tabela a si mesma ou várias vezes na mesma consulta (como aqui). Uma vez dominada, é uma ótima técnica para usar em tabelas que têm muitos relacionamentos entre as linhas (como uma lista de equipes que precisam jogar entre si!). Como outros apontaram, você precisa usar duas inner join s para fazer isso:
select
    *
from
    games g
    inner join teams t1 on
        g.teamid1 = t1.teamid
    inner join teams t2 on
        g.teamid2 = t2.teamid

Então, se seus games tabela fica assim:
GameID    TeamID1    TeamID2
----------------------------
     1          1          3
     2          4          2
     3          2          1

Você obterá o conjunto de resultados de:
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

Claro, eu usaria um alias para essas colunas no select declaração, se eu fosse eu, por uma questão de usabilidade:
select
    g.GameID,
    t1.Name as Team1,
    t2.Name as Team2
from
    ...

Dessa forma, as colunas podem ser nomeadas apropriadamente, em vez de ter o t1 e t2 colunas compartilham os mesmos nomes.

Agora, para resolver a confusão sobre o que é uma left join é. Veja, uma left join pegará todas as linhas da primeira tabela (ou da esquerda) e, em seguida, fará a correspondência de todas as linhas na condição de junção com a segunda tabela (ou da direita). Para qualquer linha da tabela à esquerda, você obterá null em todas as colunas à right tabela.

Aprofundando em um exemplo, digamos que alguém colocou um null para TeamID2 em uma das linhas por qualquer motivo. Digamos também que uma equipe de TeamID 4 existia, mas não existe mais.
GameID    TeamID1    TeamID2
----------------------------
     1          1          3
     2          4          2
     3          1       null

Agora, vamos dar uma olhada no que é uma left join seria em termos da consulta:
select
    *
from
    games g
    left join teams t1 on
        g.teamid1 = t1.teamid
    left join teams t2 on
        g.teamid2 = t2.teamid

Logicamente, isso pegará todos os nossos games e, em seguida, combiná-los com as respectivas teams . No entanto, se um TeamID não existe, obteremos null s. Vai ficar assim:
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

Portanto, uma left join será somente ser necessário se uma equipe for opcional.

No seu caso, você usará uma inner join para juntar-se a uma mesa várias vezes. Esta é uma prática muito comum e bastante útil. Ele evita algumas das armadilhas das subconsultas (especialmente no MySQL), enquanto permite que você pegue dados da tabela para comparações intratable. Isso é muito útil ao tentar encontrar a ordem de algo ou linhas relacionadas.

De qualquer forma, espero que esta resposta muito desconexa ajude alguém em algum lugar.