Redenen voor OUTER JOIN
Weet je trouwens nog dat we onze spreadsheets samenvoegden en onze kantoorschoonmaaktaken verdwenen omdat er nog geen schoonmaker was?
Als je een query als deze uitvoert:
SELECT * FROM task
Dan krijgen we dit resultaat:
ID kaart | medewerker_id | naam | deadline |
---|---|---|---|
1 | 1 | Los een bug op de frontend op | 01-06-2022 |
2 | 2 | Los een bug op de backend op | 2022-06-15 |
3 | 5 | Koop koffie | 01-07-2022 |
4 | 5 | Koop koffie | 01-08-2022 |
5 | 5 | Zal koffie kopen | 01-09-2022 |
6 | (NUL) | Ruim het kantoor op | (NUL) |
7 | 4 | Geniet van het leven | (NUL) |
8 | 6 | Geniet van het leven | (NUL) |
De taak "Kantoor leegmaken" verdwijnt als we proberen de takentabel samen te voegen met de werknemerstabel door employee_id.
Om dit probleem op te lossen, zijn er verschillende modifiers toegevoegd aan de JOIN-operator waarmee dergelijke verweesde rijen zonder een paar in een andere tabel kunnen worden opgeslagen.
Laat me je herinneren aan de klassieke vorm van de JOIN-operator:
table 1 JOIN table 2 ON
condition
We kunnen SQL Server vertellen om ervoor te zorgen dat alle gegevens uit de linkertabel (tabel1) aanwezig zijn in de samengevoegde tabel. Zelfs als er geen paar voor hen in de juiste tafel ligt. Om dit te doen, hoeft u alleen maar te schrijven:
table 1 LEFT JOIN table 2 ON condition
Als u wilt dat de samengevoegde tabel alle rijen van de rechtertabel bevat , moet u het volgende schrijven:
table 1 RIGHT JOIN table 2 ON
condition
Laten we een query schrijven die alle taken en medewerkers combineert, zodat taken zonder uitvoerder niet verloren gaan. Om dit te doen, schrijft u een query:
SELECT * FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
En het resultaat van deze vraag:
ID kaart | naam | bezigheid | salaris | leeftijd | join_date | ID kaart | medewerker_id | naam |
---|---|---|---|---|---|---|---|---|
1 | Ivanov Ivan | Programmeur | 100000 | 25 | 2012-06-30 | 1 | 1 | Los een bug op de frontend op |
2 | Petrov Petr | Programmeur | 80000 | 23 | 2013-08-12 | 2 | 2 | Los een bug op de backend op |
4 | Rabinovich Moisha | Regisseur | 200000 | 35 | 2015-05-12 | 7 | 4 | Geniet van het leven |
5 | Kirienko Anastasia | Officemanager | 40000 | 25 | 2015-10-10 | 3 | 5 | Koop koffie |
5 | Kirienko Anastasia | Officemanager | 40000 | 25 | 2015-10-10 | 4 | 5 | Koop koffie |
5 | Kirienko Anastasia | Officemanager | 40000 | 25 | 2015-10-10 | 5 | 5 | Koop koffie |
6 | Vaska | kat | 1000 | 3 | 2018-11-11 | 8 | 6 | Geniet van het leven |
(NUL) | (NUL) | (NUL) | (NUL) | (NUL) | (NUL) | 6 | (NUL) | Ruim het kantoor op |
Er is nog een rij toegevoegd aan onze tabel, en interessant genoeg zitten er veel NULL-waarden in. Alle gegevens die uit de werknemerstabel zijn gehaald, worden weergegeven als NULL, aangezien er geen uitvoerder uit de werknemerstabel was voor de taak "Kantoor opschonen".
JOIN typen
Er zijn in totaal 4 soorten JOIN's. Ze worden weergegeven in de onderstaande tabel:
Korte invoer | lange invoer | Uitleg | |
---|---|---|---|
1 | MEEDOEN | INNERLIJKE VERBINDING | Alleen records die in tabel A en B staan |
2 | LINKS DOE MEE | LINKS BUITEN DOE | Alle rijen zonder een paar van tafel A moeten dat zijn |
3 | RECHTS DOE MEE | RECHTS BUITENKANT | Alle rijen zonder een paar van tafel B moeten zijn |
4 | BUITEN VERBINDEN | VOLLEDIGE BUITENVERBINDING | Alle rijen basenparen uit tabel A en B moeten dat zijn |
Als we tabellen als sets weergeven, kan JOIN voor de eenvoud worden weergegeven als een afbeelding:
![](https://cdn.codegym.cc/images/article/66aba568-a02a-45e0-9939-6beebbb190ed/512.jpeg)
Set intersectie betekent dat er voor de ene tabel een corresponderend record is van een andere tabel waarnaar het verwijst.
Vraag uit het interview
Soms worden beginnende programmeurs gebombardeerd met een heel simpele vraag tijdens een interview. Gezien onze tabellen kan het als volgt worden geformuleerd:
"Schrijf een query die een lijst weergeeft van alle werknemers voor wie er geen taken zijn ." Laten we eerst proberen deze vraag een beetje anders te formuleren: "Schrijf een query die een lijst weergeeft van alle werknemers uit de werknemerstabel waarvoor er geen taken in de takentabel staan ." We hebben deze set nodig:![](https://cdn.codegym.cc/images/article/d3cc4f4a-b340-4b3a-9ae0-3e38eca36bb2/512.jpeg)
Er zijn veel manieren om dit probleem op te lossen, maar ik zal beginnen met de eenvoudigste: ten eerste kunt u onze tabellen samenvoegen met een LEFT JOIN en vervolgens WHERE gebruiken om alle rijen uit te sluiten waarvoor de ontbrekende gegevens zijn opgevuld met NULL's.
SELECT * FROM employee e LEFT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
En het resultaat van deze vraag:
ID kaart | naam | bezigheid | salaris | leeftijd | join_date | ID kaart | medewerker_id | naam |
---|---|---|---|---|---|---|---|---|
3 | Ivanov Sergej | Tester | 40000 | dertig | 01-01-2014 | (NUL) | (NUL) | (NUL) |
Het enige nadeel van deze oplossing is dat hier de rijen in de tabel NULL bevatten en dat we per voorwaarde een lijst met werknemers moeten weergeven.
Om dit te doen, moet u ofwel de vereiste kolommen van de werknemerstabel in SELECT opsommen, of als u ze allemaal wilt weergeven, kunt u de volgende constructie schrijven:
SELECT e.* FROM employee e, task t
De volledige aanvraag ziet er als volgt uit:
SELECT e.*
FROM employee e RIGHT JOIN task t ON e.id = t.emploee_id
WHERE t.id IS NULL
het resultaat van deze vraag:
ID kaart | naam | bezigheid | salaris | leeftijd | join_date |
---|---|---|---|---|---|
3 | Ivanov Sergej | Tester | 40000 | dertig | 01-01-2014 |
De rest van de methoden worden aan jou overgelaten voor huiswerk. Ik wil je niet het plezier ontnemen om ze zelf te vinden.