Motive pentru OUTER JOIN
Apropo, îți amintești când ne-am îmbinat foile de calcul și sarcinile noastre de curățenie în birou au dispărut pentru că nu exista încă un agent de curățenie?
Dacă executați o interogare ca aceasta:
SELECT * FROM task
Apoi obținem acest rezultat:
id | Emploee_id | Nume | Termen limită |
---|---|---|---|
1 | 1 | Remediați o eroare pe front-end | 2022-06-01 |
2 | 2 | Remediați o eroare pe backend | 2022-06-15 |
3 | 5 | Cumpără cafea | 2022-07-01 |
4 | 5 | Cumpără cafea | 2022-08-01 |
5 | 5 | Voi cumpăra cafea | 2022-09-01 |
6 | (NUL) | Curățați biroul | (NUL) |
7 | 4 | Bucură-te de viață | (NUL) |
8 | 6 | Bucură-te de viață | (NUL) |
Sarcina „Clear Office” dispare dacă încercăm să unim tabelul de sarcini cu tabelul de angajați prin employee_id.
Pentru a rezolva această problemă, la operatorul JOIN au fost adăugați diverși modificatori care permit astfel de rânduri orfane să fie stocate fără o pereche într-un alt tabel.
Permiteți-mi să vă reamintesc de forma clasică a operatorului JOIN:
table 1 JOIN table 2 ON
condition
Putem spune SQL Server să se asigure că toate datele din tabelul din stânga (table1) sunt prezente în tabelul îmbinat. Chiar dacă nu există o pereche pentru ei în tabelul potrivit. Pentru a face acest lucru, trebuie doar să scrieți:
table 1 LEFT JOIN table 2 ON condition
Dacă doriți ca tabelul alăturat să aibă toate rândurile din tabelul din dreapta , atunci trebuie să scrieți:
table 1 RIGHT JOIN table 2 ON
condition
Să scriem o interogare care va combina toate sarcinile și angajații, astfel încât sarcinile fără executor să nu se piardă. Pentru a face acest lucru, scrieți o interogare:
SELECT * FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
Și rezultatul acestei interogări:
id | Nume | ocupaţie | salariu | vârstă | Data înscrierii | id | Emploee_id | Nume |
---|---|---|---|---|---|---|---|---|
1 | Ivanov Ivan | Programator | 100000 | 25 | 30-06-2012 | 1 | 1 | Remediați o eroare pe front-end |
2 | Petrov Petr | Programator | 80000 | 23 | 12-08-2013 | 2 | 2 | Remediați o eroare pe backend |
4 | Rabinovici Moisha | Director | 200000 | 35 | 2015-05-12 | 7 | 4 | Bucură-te de viață |
5 | Kirienko Anastasia | Manager de birou | 40000 | 25 | 2015-10-10 | 3 | 5 | Cumpără cafea |
5 | Kirienko Anastasia | Manager de birou | 40000 | 25 | 2015-10-10 | 4 | 5 | Cumpără cafea |
5 | Kirienko Anastasia | Manager de birou | 40000 | 25 | 2015-10-10 | 5 | 5 | Cumpără cafea |
6 | Vaska | pisică | 1000 | 3 | 2018-11-11 | 8 | 6 | Bucură-te de viață |
(NUL) | (NUL) | (NUL) | (NUL) | (NUL) | (NUL) | 6 | (NUL) | Curățați biroul |
Un alt rând a fost adăugat la tabelul nostru și, interesant, există o mulțime de valori NULL în el. Toate datele care au fost preluate din tabelul de angajați sunt afișate ca NULL, deoarece nu a existat niciun executor din tabelul de angajați pentru sarcina „Curățare birou”.
Tipuri JOIN
Există 4 tipuri de JOIN-uri în total. Acestea sunt prezentate în tabelul de mai jos:
Scurtă intrare | intrare lungă | Explicaţie | |
---|---|---|---|
1 | A TE ALATURA | INNER JOIN | Doar înregistrările care sunt în tabelele A și B |
2 | LEFT JOIN | ÎNTREPRINDERE EXTERIOR STÂNGA | Toate rândurile fără o pereche din tabelul A trebuie să fie |
3 | ÎNSCRIEȚI DREPT | UNIRE EXTERIOR DREAPTA | Toate rândurile fără o pereche din tabelul B trebuie să fie |
4 | UNIUNEA EXTERIOARĂ | UNIRE EXTERIOR COMPLET | Toate rândurile de perechi de baze din tabelele A și B trebuie să fie |
Pentru simplitate, dacă reprezentăm tabelele ca seturi, atunci JOIN poate fi afișat ca imagine:
![](https://cdn.codegym.cc/images/article/66aba568-a02a-45e0-9939-6beebbb190ed/512.jpeg)
Setare intersecție înseamnă că pentru un tabel există o înregistrare corespunzătoare dintr-un alt tabel la care se referă.
Întrebare din interviu
Uneori, programatorii începători sunt bombardați cu o întrebare foarte simplă la un interviu. Având în vedere tabelele noastre, acesta poate fi formulat după cum urmează:
„Scrieți o interogare care va afișa o listă cu toți angajații pentru care nu există sarcini .” Mai întâi, să încercăm să reformulăm puțin această întrebare: „Scrieți o interogare care va afișa o listă cu toți angajații din tabelul de angajați pentru care nu există sarcini în tabelul de sarcini ”. Trebuie să obținem acest set:![](https://cdn.codegym.cc/images/article/d3cc4f4a-b340-4b3a-9ae0-3e38eca36bb2/512.jpeg)
Există multe modalități de a rezolva această problemă, dar voi începe cu cea mai simplă: în primul rând, puteți să vă asociați tabelele noastre cu un LEFT JOIN și apoi să utilizați WHERE pentru a exclude toate rândurile pentru care datele lipsă au fost completate cu NULL-uri.
SELECT * FROM employee e LEFT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
Și rezultatul acestei interogări:
id | Nume | ocupaţie | salariu | vârstă | Data înscrierii | id | Emploee_id | Nume |
---|---|---|---|---|---|---|---|---|
3 | Ivanov Serghei | Tester | 40000 | treizeci | 01-01-2014 | (NUL) | (NUL) | (NUL) |
Singurul dezavantaj al acestei soluții este că aici rândurile din tabel conțin NULL, iar după condiție trebuie să afișăm o listă de angajați.
Pentru a face acest lucru, fie trebuie să enumerați coloanele necesare din tabelul de angajați în SELECT, fie dacă trebuie să le afișați pe toate, puteți scrie următoarea construcție:
SELECT e.* FROM employee e, task t
Solicitarea completă va arăta astfel:
SELECT e.*
FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
rezultatul acestei interogări:
id | Nume | ocupaţie | salariu | vârstă | Data înscrierii |
---|---|---|---|---|---|
3 | Ivanov Serghei | Tester | 40000 | treizeci | 01-01-2014 |
Restul metodelor vă sunt lăsate pentru teme. Nu vreau să te privez de plăcerea de a le găsi singur.