sql >> Database >  >> RDS >> Mysql

SQL - Linker voeg 2 externe sleutels toe aan 1 primaire sleutel

Ik zie vaak dat mensen worstelen met het idee om een ​​tafel op zichzelf of meerdere keren in dezelfde zoekopdracht te plaatsen (als het ware hier). Als je het eenmaal onder de knie hebt, is het een geweldige techniek om te gebruiken op tafels met veel relaties tussen rijen (zoals een lijst met teams die tegen elkaar moeten spelen!). Zoals anderen al hebben opgemerkt, moet je twee inner join . gebruiken s om dit te bereiken:

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

Dus, als je games tabel ziet er als volgt uit:

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

U krijgt de resultatenset van:

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

Natuurlijk zou ik deze kolommen een alias geven in de select verklaring, als ik mij was, omwille van de bruikbaarheid:

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

Op deze manier kunnen kolommen de juiste naam krijgen, in plaats van de t1 en t2 kolommen hebben dezelfde namen.

Nu, om de verwarring aan te pakken over wat een left join is. Zie je, een left join zal alle rijen uit de eerste (of linker) tabel nemen en vervolgens alle rijen op de join-voorwaarde matchen met de tweede (of rechter) tabel. Voor alle rijen uit de linkertabel krijgt u null in alle kolommen aan de right tafel.

Laten we ons verdiepen in een voorbeeld, laten we zeggen dat iemand een null . heeft ingevoerd voor TeamID2 op een van de rijen om wat voor reden dan ook. Laten we ook zeggen dat een team van TeamID 4 bestond vroeger, maar bestaat niet meer.

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

Laten we nu eens kijken naar wat een left join zou zijn in termen van de vraag:

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

Logischerwijs pakt dit al onze games en koppel ze vervolgens aan de respectievelijke teams . Als er echter een TeamID niet bestaat, krijgen we null s. Het ziet er zo uit:

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

Daarom een ​​left join zal alleen nodig zijn als een team optioneel is.

In jouw geval gebruik je een inner join om meerdere keren aan een tafel te zitten. Dit is een veel voorkomende praktijk en is best handig. Het vermijdt enkele van de valkuilen van subquery's (vooral op MySQL), terwijl u gegevens uit de tabel kunt halen voor intratable-vergelijkingen. Dit is bijzonder handig wanneer u de volgorde van iets of gerelateerde rijen probeert te vinden.

Hoe dan ook, ik hoop dat dit zeer onsamenhangende antwoord iemand ergens helpt.



  1. Sqlalchemy, onbewerkte query en parameters

  2. Hoe rijen in pakjes van drie te tonen in MySQL

  3. Perl-verbinding pooling

  4. Kan mysql gem niet installeren op Mac OS X