MySQL Unire: Interior, Exterior, Stânga, Dreapta, Cruce
⚡ Rezumat inteligent
MySQL JOIN-urile combină rânduri din două sau mai multe tabele corelate într-un singur set de rezultate. Această resursă explică JOIN-urile CROSS, INNER, LEFT, RIGHT și OUTER cu interogări rulabile, date exemplu și tabele de ieșire clare pentru lucrul practic cu bazele de date.

Ce sunt JOINS?
Unirile ajută la preluarea datelor din două sau mai multe tabele de baze de date.
Tabelele sunt legate între ele folosind chei primare și străine.
Notă: JOIN este subiectul cel mai neînțeles printre cei care învață SQL. Pentru simplitate și ușurință în înțelegere, vom folosi o nouă bază de date ca exemplu de practică. După cum se arată mai jos.
Fiecare exemplu de mai jos folosește aceste două tabele. movie_id coloană în membrii indică către id coloană în filme — relația cu care se potrivește fiecare JOIN.
membrii
| id | Nume | Numele de familie | movie_id |
|---|---|---|---|
| 1 | Adam | Fierar | 1 |
| 2 | Ravi | Kumar | 2 |
| 3 | Susan | Davidson | 5 |
| 4 | Jenny | Adrianna | 8 |
| 5 | Sub vânt | Pong | 10 |
filme
| id | titlu | categorie |
|---|---|---|
| 1 | ASSASSIN'S CREED: EMBERS | Animații |
| 2 | Oțel real (2012) | Animații |
| 3 | Alvin şi veveriţele | Animații |
| 4 | Aventurile lui Tin Tin | Animații |
| 5 | Sigur (2012) | Acțiune |
| 6 | Casă sigură (2012) | Acțiune |
| 7 | GIA | 18+ |
| 8 | Termen limită 2009 | 18+ |
| 9 | Poza murdară | 18+ |
| 10 | Marley și cu mine | Romantism |
De ce ar trebui să folosim JOIN-uri?
Înainte de a analiza fiecare tip de JOIN, merită să știm de ce un JOIN este preferat în locul rulării mai multor interogări.
Acum vă puteți gândi de ce folosim JOIN-urile când putem face aceeași sarcină rulând interogări. Mai ales dacă aveți ceva experiență în programarea bazelor de date, știți că putem rula interogări una câte una, folosiți rezultatul fiecăreia în interogări succesive. Desigur, asta este posibil. Dar folosind JOIN-uri, puteți finaliza munca folosind o singură interogare cu orice parametri de căutare. Pe de altă parte MySQL poate obține performanțe mai bune cu JOIN-uri, deoarece poate folosi indexarea. Simpla utilizare a unei singure interogări JOIN, în loc de rularea mai multor interogări, reduce supraîncărcarea serverului. Folosind mai multe interogări în schimb, care duce la mai multe transferuri de date între MySQL și aplicații (software). Mai mult, necesită mai multe manipulări de date și în aplicația.
Este clar că putem realiza mai bine MySQL și performanța aplicației prin utilizarea JOIN-urilor.
Tipuri de JOIN-uri
MySQL acceptă mai multe tipuri JOIN, fiecare răspunzând la o întrebare diferită despre aceleași două tabele. Tabelul de mai jos le compară; fiecare tip este apoi demonstrat cu o interogare și rezultatul acesteia.
| Tip JOIN | Rânduri returnate | NULL-uri în rezultat? | Utilizare tipică |
|---|---|---|---|
| CROS JOIN | Fiecare rând al tabelului A este asociat cu fiecare rând al tabelului B | Nu | Generarea tuturor combinațiilor posibile |
| INNER JOIN | Doar rândurile care corespund condiției în ambele tabele | Nu | Membri care au închiriat efectiv un film |
| REDUCEREA LOCULUI | Toate rândurile din tabelul din stânga, plus potrivirile din dreapta | Da, pe partea dreaptă | Toate filmele, chiar și cele neînchiriate niciodată |
| ÎNSCRIEȚI DREPT | Toate rândurile din tabelul din dreapta, plus potrivirile din stânga | Da, pe partea stângă | Toate filmele, chiar și fără niciun membru atașat |
CROS JOIN
Cross JOIN este cea mai simplă formă de JOIN care potrivește fiecare rând dintr-un tabel de bază de date cu toate rândurile altuia.
Cu alte cuvinte, ne oferă combinații ale fiecărui rând din primul tabel cu toate înregistrările din al doilea tabel.
Să presupunem că vrem să obținem toate înregistrările membrilor față de toate înregistrările filmului, putem folosi scriptul prezentat mai jos pentru a obține rezultatele dorite.
SELECT * FROM `movies` CROSS JOIN `members`
Executarea scriptului de mai sus în MySQL banc de lucru ne oferă următoarele rezultate.
| id | title | id | first_name | last_name | movie_id | |
|---|---|---|---|---|---|---|
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 1 | Adam | Smith | 1 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 2 | Ravi | Kumar | 2 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 3 | Susan | Davidson | 5 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 4 | Jenny | Adrianna | 8 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 6 | Lee | Pong | 10 |
| 2 | Real Steel(2012) | Animations | 1 | Adam | Smith | 1 |
| 2 | Real Steel(2012) | Animations | 2 | Ravi | Kumar | 2 |
| 2 | Real Steel(2012) | Animations | 3 | Susan | Davidson | 5 |
| 2 | Real Steel(2012) | Animations | 4 | Jenny | Adrianna | 8 |
| 2 | Real Steel(2012) | Animations | 6 | Lee | Pong | 10 |
| 3 | Alvin and the Chipmunks | Animations | 1 | Adam | Smith | 1 |
| 3 | Alvin and the Chipmunks | Animations | 2 | Ravi | Kumar | 2 |
| 3 | Alvin and the Chipmunks | Animations | 3 | Susan | Davidson | 5 |
| 3 | Alvin and the Chipmunks | Animations | 4 | Jenny | Adrianna | 8 |
| 3 | Alvin and the Chipmunks | Animations | 6 | Lee | Pong | 10 |
| 4 | The Adventures of Tin Tin | Animations | 1 | Adam | Smith | 1 |
| 4 | The Adventures of Tin Tin | Animations | 2 | Ravi | Kumar | 2 |
| 4 | The Adventures of Tin Tin | Animations | 3 | Susan | Davidson | 5 |
| 4 | The Adventures of Tin Tin | Animations | 4 | Jenny | Adrianna | 8 |
| 4 | The Adventures of Tin Tin | Animations | 6 | Lee | Pong | 10 |
| 5 | Safe (2012) | Action | 1 | Adam | Smith | 1 |
| 5 | Safe (2012) | Action | 2 | Ravi | Kumar | 2 |
| 5 | Safe (2012) | Action | 3 | Susan | Davidson | 5 |
| 5 | Safe (2012) | Action | 4 | Jenny | Adrianna | 8 |
| 5 | Safe (2012) | Action | 6 | Lee | Pong | 10 |
| 6 | Safe House(2012) | Action | 1 | Adam | Smith | 1 |
| 6 | Safe House(2012) | Action | 2 | Ravi | Kumar | 2 |
| 6 | Safe House(2012) | Action | 3 | Susan | Davidson | 5 |
| 6 | Safe House(2012) | Action | 4 | Jenny | Adrianna | 8 |
| 6 | Safe House(2012) | Action | 6 | Lee | Pong | 10 |
| 7 | GIA | 18+ | 1 | Adam | Smith | 1 |
| 7 | GIA | 18+ | 2 | Ravi | Kumar | 2 |
| 7 | GIA | 18+ | 3 | Susan | Davidson | 5 |
| 7 | GIA | 18+ | 4 | Jenny | Adrianna | 8 |
| 7 | GIA | 18+ | 6 | Lee | Pong | 10 |
| 8 | Deadline(2009) | 18+ | 1 | Adam | Smith | 1 |
| 8 | Deadline(2009) | 18+ | 2 | Ravi | Kumar | 2 |
| 8 | Deadline(2009) | 18+ | 3 | Susan | Davidson | 5 |
| 8 | Deadline(2009) | 18+ | 4 | Jenny | Adrianna | 8 |
| 8 | Deadline(2009) | 18+ | 6 | Lee | Pong | 10 |
| 9 | The Dirty Picture | 18+ | 1 | Adam | Smith | 1 |
| 9 | The Dirty Picture | 18+ | 2 | Ravi | Kumar | 2 |
| 9 | The Dirty Picture | 18+ | 3 | Susan | Davidson | 5 |
| 9 | The Dirty Picture | 18+ | 4 | Jenny | Adrianna | 8 |
| 9 | The Dirty Picture | 18+ | 6 | Lee | Pong | 10 |
| 10 | Marley and me | Romance | 1 | Adam | Smith | 1 |
| 10 | Marley and me | Romance | 2 | Ravi | Kumar | 2 |
| 10 | Marley and me | Romance | 3 | Susan | Davidson | 5 |
| 10 | Marley and me | Romance | 4 | Jenny | Adrianna | 8 |
| 10 | Marley and me | Romance | 6 | Lee | Pong | 10 |
INNER JOIN
O joncțiune CROSS JOIN returnează fiecare pereche posibilă, ceea ce este rareori ceea ce doriți. O joncțiune INNER restrânge rezultatul la perechile care sunt de fapt înrudite.
JOIN interior este folosit pentru a returna rânduri din ambele tabele care satisfac condiția dată.
Să presupunem că doriți să obțineți o listă de membri care au închiriat filme, împreună cu titlurile filmelor închiriate de aceștia. Puteți utiliza pur și simplu un INNER JOIN pentru aceasta, care returnează rânduri din ambele tabele care îndeplinesc condițiile date.
SELECT members.`first_name` , members.`last_name` , movies.`title` FROM members ,movies WHERE movies.`id` = members.`movie_id`
Executarea scriptului de mai sus da
| first_name | last_name | title |
|---|---|---|
| Adam | Smith | ASSASSIN'S CREED: EMBERS |
| Ravi | Kumar | Real Steel(2012) |
| Susan | Davidson | Safe (2012) |
| Jenny | Adrianna | Deadline(2009) |
| Lee | Pong | Marley and me |
Rețineți că scriptul de rezultate de mai sus poate fi scris și după cum urmează pentru a obține aceleași rezultate.
SELECT A.`first_name` , A.`last_name` , B.`title` FROM `members` AS A INNER JOIN `movies` AS B ON B.`id` = A.`movie_id`
JOIN-urile exterioare
O INNER JOIN elimină în mod silențios rândurile care nu au partener. Când acele rânduri nepotrivite contează, o OUTER JOIN este alegerea potrivită.
MySQL JOIN-urile externe returnează toate înregistrările care se potrivesc din ambele tabele.
Poate detecta înregistrările care nu au nicio potrivire în tabelul alăturat. Se întoarce NULL valori pentru înregistrările tabelului îmbinat dacă nu se găsește nicio potrivire.
Sună confuz? Să luăm un exemplu –
REDUCEREA LOCULUI
Să presupunem că acum doriți să obțineți titluri ale tuturor filmelor împreună cu numele membrilor care le-au închiriat. Este clar că unele filme nu au fost închiriate de nimeni. Putem folosi pur și simplu REDUCEREA LOCULUI pentru scopul.
LEFT JOIN returnează toate rândurile din tabelul din stânga chiar dacă nu au fost găsite rânduri care să se potrivească în tabelul din dreapta. Acolo unde nu au fost găsite potriviri în tabelul din dreapta, este returnat NULL.
SELECT A.`title` , B.`first_name` , B.`last_name` FROM `movies` AS A LEFT JOIN `members` AS B ON B.`movie_id` = A.`id`
Executarea scriptului de mai sus în MySQL workbench dă. Puteți vedea că în rezultatul returnat, listat mai jos, pentru filmele care nu sunt închiriate, câmpurile cu numele membrului au valori NULL. Aceasta înseamnă că nu a fost găsit niciun membru potrivit în tabelul de membri pentru filmul respectiv.
| title | first_name | last_name |
|---|---|---|
| ASSASSIN'S CREED: EMBERS | Adam | Smith |
| Real Steel(2012) | Ravi | Kumar |
| Safe (2012) | Susan | Davidson |
| Deadline(2009) | Jenny | Adrianna |
| Marley and me | Lee | Pong |
| Alvin and the Chipmunks | NULL | NULL |
| The Adventures of Tin Tin | NULL | NULL |
| Safe House(2012) | NULL | NULL |
| GIA | NULL | NULL |
| The Dirty Picture | NULL | NULL |
ÎNSCRIEȚI DREPT
RIGHT JOIN este, evident, opusul LEFT JOIN. RIGHT JOIN returnează toate coloanele din tabelul din dreapta, chiar dacă nu au fost găsite rânduri care să se potrivească în tabelul din stânga. Acolo unde nu au fost găsite potriviri în tabelul din stânga, este returnat NULL.
În exemplul nostru, să presupunem că trebuie să obțineți numele membrilor și filmele închiriate de aceștia. Acum avem un nou membru care nu a închiriat încă niciun film
SELECT A.`first_name` , A.`last_name`, B.`title` FROM `members` AS A RIGHT JOIN `movies` AS B ON B.`id` = A.`movie_id`
Executarea scriptului de mai sus în MySQL workbench dă următoarele rezultate.
| first_name | last_name | title |
|---|---|---|
| Adam | Smith | ASSASSIN'S CREED: EMBERS |
| Ravi | Kumar | Real Steel(2012) |
| Susan | Davidson | Safe (2012) |
| Jenny | Adrianna | Deadline(2009) |
| Lee | Pong | Marley and me |
| NULL | NULL | Alvin and the Chipmunks |
| NULL | NULL | The Adventures of Tin Tin |
| NULL | NULL | Safe House(2012) |
| NULL | NULL | GIA |
| NULL | NULL | The Dirty Picture |
Clauzele „ON” și „UTILIZARE”.
Fiecare interogare de până acum a găsit rânduri potrivite cu o clauză ON. MySQL oferă o alternativă mai scurtă atunci când coloanele potrivite au același nume.
În exemplele de interogare JOIN de mai sus, am folosit clauza ON pentru a potrivi înregistrările dintre tabel.
Clauza USING poate fi folosită și în același scop. Diferența cu UTILIZAREA este trebuie să aibă nume identice pentru coloanele potrivite din ambele tabele.
În tabelul „filme” am folosit până acum cheia primară cu numele „id”. Ne-am referit la aceeași în tabelul „membri” cu numele „movie_id”.
Să redenumim tabelele „filme” câmpul „id” pentru a avea numele „movie_id”. Facem acest lucru pentru a avea nume de câmpuri identice.
ALTER TABLE `movies` CHANGE `id` `movie_id` INT( 11 ) NOT NULL AUTO_INCREMENT;
În continuare, să folosim UTILIZARE cu exemplul de mai sus LEFT JOIN.
SELECT A.`title` , B.`first_name` , B.`last_name` FROM `movies` AS A LEFT JOIN `members` AS B USING ( `movie_id` )
În afară de utilizarea ON și UTILIZARE cu JOIN-uri poti folosi multe altele MySQL clauze ca A SE GRUPA CU, UNDE și chiar funcții precum USM, AVG, Etc




