Joins#

%LOAD ../data/employees.db

Tot nu toe hebben we vrijwel alleen nog maar informatie gehaald uit één tabel, maar heel vaak zul je informatie op willen halen die uit verschillende tabellen komt. Stel bijvoorbeeld dat je alle achternamen wil tonen met hun department_id en de department_name. De last_name staat in de tabel employees, department_name staat in departments en het department_id staat zowel in employees als in departments. Probeer onderstaande query en je zult zien dat je een foutmelding krijgt!

SELECT last_name, department_id, department_name
FROM employees, departments;
Error: ambiguous column name: department_id

Het systeem meldt dat de kolom department_id ambigu (tweeslachtig) is. Dat komt omdat department_id zowel in employees staat als in departments en het systeem weet niet welke kolom je bedoelt. Door het gebruik van een alias voor de tabellen employees en departments kun je aangeven uit welke tabel department_id genomen moet worden. We passen nu de query aan door een alias toe te voegen aan de beide tabellen. De tabel employees noemen we tijdelijk ‘e’ en de tabel departments noemen we tijdelijk ‘d’. De query zal het nu wel doen, maar we hebben een ander probleem!

SELECT e.last_name, d.department_id, d.department_name
FROM employees e, departments d
LIMIT 20;
last_name department_id department_name
King 10 Administration
King 20 Marketing
King 50 Shipping
King 60 IT
King 80 Sales
King 90 Executive
King 110 Accounting
King 190 Contracting
Kochhar 10 Administration
Kochhar 20 Marketing
Kochhar 50 Shipping
Kochhar 60 IT
Kochhar 80 Sales
Kochhar 90 Executive
Kochhar 110 Accounting
Kochhar 190 Contracting
De Haan 10 Administration
De Haan 20 Marketing
De Haan 50 Shipping
De Haan 60 IT

Er verschijnen 160 rijen en je ziet dat alle employees allemaal op alle departments werken. Er zijn 20 employees en 8 departments en je krijgt dus 20 x 8 = 160 rijen terug. In onderstaande afbeelding worden enkel King en Kochar getoond. In zo’n geval spreekt men van een Cartesisch product.

Je begrijpt dat dit niet de bedoeling is. King en Kochar werken alleen maar op de afdeling Executive. Om de juiste gegevens te krijgen moet je iets heel belangrijks doen en dat is dat je een join voorwaarde inbouwt. Dat kan bijvoorbeeld op de volgende manier met een WHERE component.

SELECT e.last_name, d.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;
last_name department_id department_name
King 90 Executive
Kochhar 90 Executive
De Haan 90 Executive
Hunold 60 IT
Ernst 60 IT
Lorentz 60 IT
Mourgos 50 Shipping
Rajs 50 Shipping
Davies 50 Shipping
Matos 50 Shipping
Vargas 50 Shipping
Zlotkey 80 Sales
Abel 80 Sales
Taylor 80 Sales
Whalen 10 Administration
Hartstein 20 Marketing
Fay 20 Marketing
Higgins 110 Accounting
Gietz 110 Accounting

Nu krijg je de juiste informatie met 19 rijen. Geen 20 want Grant werkt niet op een afdeling.

We noemen dit een equijoin. Equi (gelijk) slaat op het is-gelijk-teken. Er is een aantal mogelijkheden om de juiste informatie uit verschillende tabellen te halen. Hierna komen ze allemaal aan bod zodat je ze herkent.

In de praktijk wordt echter vooral de LEFT JOIN ON gebruikt en daar moeten we de grootste aandacht naar uit laten gaan.

Cross join#

Een CROSS JOIN voegt elke rij van een tabel samen met elke andere rij in een andere tabel. Als je een tabel hebt met twintig rijen (employees bijvoorbeeld) die je samenvoegt met een tabel van acht rijen (departments bijvoorbeeld), dan krijg je 160 rijen als resultaat. Elke werknemer (employee) wordt aan elke afdeling (department) gekoppeld. In zo’n geval spreekt men van een Cartesisch product, zoals al eerder besproken.

SELECT last_name, department_name
FROM employees CROSS JOIN departments
LIMIT 20;
last_name department_name
King Administration
King Marketing
King Shipping
King IT
King Sales
King Executive
King Accounting
King Contracting
Kochhar Administration
Kochhar Marketing
Kochhar Shipping
Kochhar IT
Kochhar Sales
Kochhar Executive
Kochhar Accounting
Kochhar Contracting
De Haan Administration
De Haan Marketing
De Haan Shipping
De Haan IT

Je begrijpt dat dit niet de bedoeling kan zijn. CROSS kan overigens gewoon worden weggelaten voor hetzelfde effect.

SELECT last_name, department_name
FROM employees JOIN departments
LIMIT 20;
last_name department_name
King Administration
King Marketing
King Shipping
King IT
King Sales
King Executive
King Accounting
King Contracting
Kochhar Administration
Kochhar Marketing
Kochhar Shipping
Kochhar IT
Kochhar Sales
Kochhar Executive
Kochhar Accounting
Kochhar Contracting
De Haan Administration
De Haan Marketing
De Haan Shipping
De Haan IT

De CROSS JOIN wordt in de praktijk zelden gebruikt, maar je kunt bijvoorbeeld testen of kolomnamen en tabelnamen kloppen in een query en daarna pas de query verfijnen.

Natural join#

Uit twee tabellen wordt één resultaattabel afgeleid, waarvan de rijen bestaan uit alle mogelijke combinaties van een rij uit de ene met een rij uit de andere tabel, mits beide rijen voor alle gelijknamige kolomnamen dezelfde waarden hebben en ze moeten van hetzelfde datatype zijn. Als de kolommen dezelfde naam hebben maar van een verschillend datatype zijn, krijg je een foutmelding. Een combinatie van twee rijen ontstaat door ze aan elkaar te plakken en de dubbele waarden slechts eenmaal in het resultaat op te nemen. Het DBMS leidt de voorwaarde van de join dus zelf af door te kijken naar de namen van de kolommen in de beide tabellen.

De tabel employees heeft een kolom job_id. Dit job_id verwijst naar de kolom met dezelfde naam in de tabel jobs. Ze zijn beide van het type VARCHAR(10). Dus job_id staat zowel in de tabel employees als in de tabel jobs. Maar job_title staat alleen maar in de tabel jobs.

Als je nu een overzicht wil maken van personeelsleden met daarin ook hun job_title dan gebruik je de volgende query:

SELECT first_name, last_name, job_id, job_title
FROM employees NATURAL JOIN jobs;
first_name last_name job_id job_title
Steven King AD_PRES President
Neena Kochhar AD_VP Administration Vice President
Lex De Haan AD_VP Administration Vice President
Alexander Hunold IT_PROG Programmer
Bruce Ernst IT_PROG Programmer
Diana Lorentz IT_PROG Programmer
Kevin Mourgos ST_MAN Stock Manager
Trenna Rajs ST_CLERK Stock Clerk
Curtis Davies ST_CLERK Stock Clerk
Randall Matos ST_CLERK Stock Clerk
Peter Vargas ST_CLERK Stock Clerk
Eleni Zlotkey SA_MAN Sales Manager
Ellen Abel SA_REP Sales Representative
Jonathon Taylor SA_REP Sales Representative
Kimberely Grant SA_REP Sales Representative
Jennifer Whalen AD_ASST Administration Assistant
Michael Hartstein MK_MAN Marketing Manager
Pat Fay MK_REP Marketing Representative
Shelley Higgins AC_MGR Accounting Manager
William Gietz AC_ACCOUNT Public Accountant

Nog een voorbeeld. Je wil alle department_names tonen met de city. De department_names staan in de tabel departments en city staat in de tabel locations. In beide tabellen staat een kolom location_id van het type SMALLINT(6).

SELECT department_name, city
FROM departments NATURAL JOIN locations;
department_name city
Administration Seattle
Marketing Toronto
Shipping South San Francisco
IT Southlake
Sales Oxford
Executive Seattle
Accounting Seattle
Contracting Seattle

Het is mogelijk WHERE te gebruiken met een natural join.

SELECT first_name, last_name, job_id, job_title
FROM employees NATURAL JOIN jobs
WHERE last_name = 'King';
first_name last_name job_id job_title
Steven King AD_PRES President

Waarschuwing

Het gebruik van de NATURAL JOIN wordt sterk afgeraden aangezien je de kans loopt onbetrouwbare informatie op te halen op deze manier. In de praktijk wordt de NATURAL JOIN dan ook zelden of niet gebruikt. De enige reden dat deze hier genoemd wordt, is dat je moet weten dat hij bestaat, maar gebruik hem dus niet!

Neem bijvoorbeeld onderstaande query.

SELECT first_name, last_name, job_id, department_name
FROM employees NATURAL JOIN departments;
first_name last_name job_id department_name
Neena Kochhar AD_VP Executive
Lex De Haan AD_VP Executive
Bruce Ernst IT_PROG IT
Diana Lorentz IT_PROG IT
Trenna Rajs ST_CLERK Shipping
Curtis Davies ST_CLERK Shipping
Randall Matos ST_CLERK Shipping
Peter Vargas ST_CLERK Shipping
Ellen Abel SA_REP Sales
Jonathon Taylor SA_REP Sales
Pat Fay MK_REP Marketing
William Gietz AC_ACCOUNT Accounting

Er zitten twintig employees in de tabel employees en met deze NATURAL JOIN van de tabellen employees en departments komen er maar twaalf rijen terug!

Inner join#

Met een INNER JOIN worden de rijen getoond die in twee of meerdere tabellen voorkomen. In plaats van INNER JOIN kun je gewoon JOIN gebruiken. Een JOIN maak je met USING of met JOIN ON. Een INNER JOIN wordt ook wel een SIMPLE JOIN genoemd. De eerste tabel heeft zwart, blauw en wit. De tweede tabel heeft blauw, wit en oranje. Alleen blauw en wit komen voor in beide tabellen en die worden dan getoond. Zwart en oranje worden niet getoond.

../_images/inner-join.png

Fig. 1 INNER JOIN#

SELECT last_name, department_name
FROM employees INNER JOIN departments USING(department_id);
last_name department_name
King Executive
Kochhar Executive
De Haan Executive
Hunold IT
Ernst IT
Lorentz IT
Mourgos Shipping
Rajs Shipping
Davies Shipping
Matos Shipping
Vargas Shipping
Zlotkey Sales
Abel Sales
Taylor Sales
Whalen Administration
Hartstein Marketing
Fay Marketing
Higgins Accounting
Gietz Accounting
SELECT last_name, department_name
FROM employees JOIN departments USING(department_id);
last_name department_name
King Executive
Kochhar Executive
De Haan Executive
Hunold IT
Ernst IT
Lorentz IT
Mourgos Shipping
Rajs Shipping
Davies Shipping
Matos Shipping
Vargas Shipping
Zlotkey Sales
Abel Sales
Taylor Sales
Whalen Administration
Hartstein Marketing
Fay Marketing
Higgins Accounting
Gietz Accounting

Grant heeft geen department_id en komt daarom niet voor in de uitvoer.

Join using#

Met USING geef je specifiek aan welke kolommen gebruikt moeten worden voor de JOIN.

SELECT first_name, last_name, department_id, department_name FROM employees JOIN departments USING(department_id);

Het is mogelijk drie of meer tabellen te gebruiken om alle informatie in één uitvoer te zetten. Als je drie tabellen nodig hebt voor de juiste informatie, noem je de eerste tabel bij FROM en volgen er daarna twee JOINS.

SELECT last_name, department_name, city
FROM employees
 JOIN departments USING(department_id)
 JOIN locations USING(location_id);
last_name department_name city
King Executive Seattle
Kochhar Executive Seattle
De Haan Executive Seattle
Hunold IT Southlake
Ernst IT Southlake
Lorentz IT Southlake
Mourgos Shipping South San Francisco
Rajs Shipping South San Francisco
Davies Shipping South San Francisco
Matos Shipping South San Francisco
Vargas Shipping South San Francisco
Zlotkey Sales Oxford
Abel Sales Oxford
Taylor Sales Oxford
Whalen Administration Seattle
Hartstein Marketing Toronto
Fay Marketing Toronto
Higgins Accounting Seattle
Gietz Accounting Seattle

Join on#

JOIN ON is de allerbelangrijkste manier om tabellen aan elkaar te knopen en daarom moet er heel veel geoefend worden met JOIN ON! JOIN ON werkt hetzelfde als JOIN USING maar JOIN ON kun je ook gebruiken als de kolomnamen van de twee verschillende tabellen niet exact hetzelfde zijn. Na ON benoem je dan de kolomnamen die aan elkaar gelijk moeten zijn. Eerst noem je de tabel, dan volgt er een punt en dan volgt de kolomnaam. Er zijn twee kolomnamen die je met elkaar wil vergelijken, maar ze heten anders. In de tabel employees heet de kolom salary en in de tabel job_grades heet de kolom lowest_sal. In onderstaand voorbeeld vergelijk je salary van employees met lowest_sal van job_grades. Deze personen zitten dus in de laagste salarisschaal van job_grade.

SELECT first_name, last_name, salary, lowest_sal, highest_sal, grade_level
FROM employees JOIN job_grades ON employees.salary = job_grades.lowest_sal;
first_name last_name salary lowest_sal highest_sal grade_level
Bruce Ernst 6000 6000.0 9999.0 C
Pat Fay 6000 6000.0 9999.0 C

Met aliassen maak je deze query als volgt wat netter.

SELECT e.first_name
,      e.last_name
,      e.salary
,      g.lowest_sal
,      g.highest_sal
,      g.grade_level
FROM employees e JOIN job_grades g ON e.salary = g.lowest_sal;
first_name last_name salary lowest_sal highest_sal grade_level
Bruce Ernst 6000 6000.0 9999.0 C
Pat Fay 6000 6000.0 9999.0 C

Nog een voorbeeld van employees die het minimum salaris hebben van de job_id die ze hebben. De tabellen employees en jobs worden samengevoegd op kolommen die niet dezelfde kolomnaam hebben. Merk op dat salary twee decimalen heeft en dat min_salary en max_salary geen decimalen hebben. De kolom salary is van het type DECIMAL en de kolommen min_salary en max_salary zijn van het type INT.

SELECT e.first_name, e.last_name, e.salary, j.min_salary, j.max_salary
FROM employees e JOIN jobs j ON e.salary = j.min_salary;
first_name last_name salary min_salary max_salary
Alexander Hunold 9000 9000 15000
Bruce Ernst 6000 6000 12000
Diana Lorentz 4200 4200 9000
Pat Fay 6000 6000 12000

JOIN ON werkt uiteraard ook als de kolomnamen van de verschillende tabellen wel hetzelfde zijn.

SELECT last_name, job_title
FROM employees JOIN jobs ON employees.job_id = jobs.job_id;
last_name job_title
King President
Kochhar Administration Vice President
De Haan Administration Vice President
Hunold Programmer
Ernst Programmer
Lorentz Programmer
Mourgos Stock Manager
Rajs Stock Clerk
Davies Stock Clerk
Matos Stock Clerk
Vargas Stock Clerk
Zlotkey Sales Manager
Abel Sales Representative
Taylor Sales Representative
Grant Sales Representative
Whalen Administration Assistant
Hartstein Marketing Manager
Fay Marketing Representative
Higgins Accounting Manager
Gietz Public Accountant

Het is mogelijk drie of meer tabellen te gebruiken om alle informatie in één uitvoer te zetten. Voor de leesbaarheid kun je dan de joins onder elkaar zetten.

SELECT last_name, department_name, city
FROM employees
 JOIN departments ON (employees.department_id = departments.department_id) 
 JOIN locations ON departments.location_id = locations.location_id;
last_name department_name city
King Executive Seattle
Kochhar Executive Seattle
De Haan Executive Seattle
Hunold IT Southlake
Ernst IT Southlake
Lorentz IT Southlake
Mourgos Shipping South San Francisco
Rajs Shipping South San Francisco
Davies Shipping South San Francisco
Matos Shipping South San Francisco
Vargas Shipping South San Francisco
Zlotkey Sales Oxford
Abel Sales Oxford
Taylor Sales Oxford
Whalen Administration Seattle
Hartstein Marketing Toronto
Fay Marketing Toronto
Higgins Accounting Seattle
Gietz Accounting Seattle

Outer join#

Als je rijen uit meerdere tabellen ophaalt, kan het zijn dat sommige rijen uit de ene tabel niet gekoppeld (ge-joined) kunnen worden (door de join-voorwaarde) met een rij uit de andere tabel. Zo’n rij komt dan niet in je query resultaat. Soms wil je die rijen uit die ene tabel toch in je resultaat. Door gebruik te maken van een outer-join zal het DBMS deze rijen dan toch in je resultaat behouden, waarbij ze ge-joined worden met een (denkbeeldige) geheel lege rij (allemaal NULL’s) uit de andere tabel. In het voorbeeld van onze database heeft werknemer Grant bijvoorbeeld geen department_id (ze werkt dus niet op een bepaalde afdeling) en er is een department waar niemand werkt (Contracting).

../_images/outer-join-table.png

Fig. 2 Tabel met NULL waarden.#

Als we de tabellen employees en departments samenvoegen met een INNER JOIN krijgen we een uitvoer van 19 records terwijl er 20 werknemers zijn. Grant staat hier namelijk niet bij.

SELECT first_name, last_name, department_id, department_name
FROM employees JOIN departments USING(department_id);
first_name last_name department_id department_name
Steven King 90 Executive
Neena Kochhar 90 Executive
Lex De Haan 90 Executive
Alexander Hunold 60 IT
Bruce Ernst 60 IT
Diana Lorentz 60 IT
Kevin Mourgos 50 Shipping
Trenna Rajs 50 Shipping
Curtis Davies 50 Shipping
Randall Matos 50 Shipping
Peter Vargas 50 Shipping
Eleni Zlotkey 80 Sales
Ellen Abel 80 Sales
Jonathon Taylor 80 Sales
Jennifer Whalen 10 Administration
Michael Hartstein 20 Marketing
Pat Fay 20 Marketing
Shelley Higgins 110 Accounting
William Gietz 110 Accounting

Dit soort problemen kunnen we oplossen met LEFT JOIN en RIGHT JOIN.

Left join#

Bij een LEFT JOIN worden rijen uit de linker tabel in het query resultaat behouden als ze niet met een rij uit de rechter tabel gejoined kunnen worden. In plaats van LEFT JOIN wordt ook wel LEFT OUTER JOIN gebruikt. In de eerste tabel komen zwart, blauw en wit voor en in de tweede tabel blauw, wit en oranje. Met een LEFT JOIN worden alle rijen getoond van de linker tabel, dus in dit geval zwart, blauw en wit. Maar van de rechter tabel wordt alleen maar blauw en wit getoond en oranje niet.

SELECT last_name, department_name
FROM employees 
  LEFT JOIN departments ON employees.department_id = departments.department_id;
last_name department_name
King Executive
Kochhar Executive
De Haan Executive
Hunold IT
Ernst IT
Lorentz IT
Mourgos Shipping
Rajs Shipping
Davies Shipping
Matos Shipping
Vargas Shipping
Zlotkey Sales
Abel Sales
Taylor Sales
Grant
Whalen Administration
Hartstein Marketing
Fay Marketing
Higgins Accounting
Gietz Accounting

Je ziet dat Grant nu wel in het linker rijtje voorkomt, ondanks het feit dat ze geen department_name heeft. En dat komt dus door de toevoeging van LEFT bij de JOIN. Bij een LEFT JOIN is het linkerrijtje het langst.

Right join#

Bij een RIGHT JOIN worden rijen uit de rechter tabel in het query resultaat behouden als ze niet met een rij uit de linker tabel gejoined kunnen worden. In plaats van RIGHT JOIN wordt ook wel RIGHT OUTER JOIN gebruikt. IN de linker tabel komen zwart, blauw en wit voor en in de rechter tabel blauw, wit en oranje. Zwart wordt dus niet getoond, want die staat alleen maar aan de linkerkant. Oranje wordt wel getoond.

SELECT last_name, department_name
FROM employees 
  RIGHT JOIN departments ON employees.department_id = departments.department_id;
last_name department_name
King Executive
Kochhar Executive
De Haan Executive
Hunold IT
Ernst IT
Lorentz IT
Mourgos Shipping
Rajs Shipping
Davies Shipping
Matos Shipping
Vargas Shipping
Zlotkey Sales
Abel Sales
Taylor Sales
Whalen Administration
Hartstein Marketing
Fay Marketing
Higgins Accounting
Gietz Accounting
Contracting

Je ziet dat Contracting nu wel in het rechterrijtje voorkomt, ondanks het feit dat er niemand op die afdeling werkt. En dat komt dus door de toevoeging van RIGHT bij de JOIN. Bij een RIGHT JOIN is het rechterrijtje het langst.

Waarschuwing

In de praktijk worden RIGHT JOINS niet gebruikt. Het is niet erg nuttig een overzicht te laten beginnen met een kolom met NULL. Bovendien kun je een OUTER JOIN namaken met een LEFT JOIN door de kolomnamen om te draaien.

SELECT department_name, last_name
FROM departments 
  LEFT JOIN employees ON departments.department_id = employees.department_id;
department_name last_name
Administration Whalen
Marketing Fay
Marketing Hartstein
Shipping Davies
Shipping Matos
Shipping Mourgos
Shipping Rajs
Shipping Vargas
IT Ernst
IT Hunold
IT Lorentz
Sales Abel
Sales Taylor
Sales Zlotkey
Executive De Haan
Executive King
Executive Kochhar
Accounting Gietz
Accounting Higgins
Contracting

Full join#

Je kunt een LEFT JOIN en een RIGHT JOIN combineren tot een FULL JOIN. Je krijgt dan alle rijen van een kolom uit de ene tabel gecombineerd met alle rijen van een kolom uit een andere tabel, ongeacht of er een match is of niet. In plaats van FULL JOIN wordt ook wel FULL OUTER JOIN gebruikt.

SELECT employees.last_name, departments.department_id, departments.department_name
FROM employees
 FULL OUTER JOIN departments ON employees.department_id = departments.department_id;
last_name department_id department_name
King 90 Executive
Kochhar 90 Executive
De Haan 90 Executive
Hunold 60 IT
Ernst 60 IT
Lorentz 60 IT
Mourgos 50 Shipping
Rajs 50 Shipping
Davies 50 Shipping
Matos 50 Shipping
Vargas 50 Shipping
Zlotkey 80 Sales
Abel 80 Sales
Taylor 80 Sales
Grant
Whalen 10 Administration
Hartstein 20 Marketing
Fay 20 Marketing
Higgins 110 Accounting
Gietz 110 Accounting
190 Contracting

De FULL OUTER JOIN is ANSI-standaard maar wordt niet ondersteund in MySQL.

Self join#

Het is mogelijk een tabel met zichzelf te joinen door twee aliassen te gebruiken voor dezelfde tabel. De database denkt dan dat er twee tabellen zijn. In de tabel employees staat bij manager_id wie de manager is van de employee. Dat nummer bij manager_id verwijst naar het employee_id.

  • Je ziet dat King geen manager_id heeft, hij is de hoogste baas.

  • Kochar heeft als manager_id 100 en dat is dus King.

  • Hunold heeft als manager_id 102 en dat is dus De Haan.

  • et cetera

Als je een alias gaat kiezen, moet je een duidelijke naam nemen. In dit geval hebben we worker voor de werknemers gekozen en manager voor de managers. We kunnen nu een overzicht maken met de werknemers en hun managers.

SELECT worker.last_name, worker.manager_id, manager.last_name AS manager_name
FROM employees worker 
  JOIN employees manager ON worker.manager_id = manager.employee_id;
last_name manager_id manager_name
Kochhar 100 King
De Haan 100 King
Hunold 102 De Haan
Ernst 103 Hunold
Lorentz 103 Hunold
Mourgos 100 King
Rajs 124 Mourgos
Davies 124 Mourgos
Matos 124 Mourgos
Vargas 124 Mourgos
Zlotkey 100 King
Abel 149 Zlotkey
Taylor 149 Zlotkey
Grant 149 Zlotkey
Whalen 101 Kochhar
Hartstein 100 King
Fay 201 Hartstein
Higgins 101 Kochhar
Gietz 205 Higgins

En als je daar KING bij wil hebben, maak je er een LEFT JOIN van.

SELECT worker.last_name, worker.manager_id, manager.last_name AS manager_name
FROM employees worker 
  LEFT JOIN employees manager ON worker.manager_id = manager.employee_id;
last_name manager_id manager_name
King
Kochhar 100 King
De Haan 100 King
Hunold 102 De Haan
Ernst 103 Hunold
Lorentz 103 Hunold
Mourgos 100 King
Rajs 124 Mourgos
Davies 124 Mourgos
Matos 124 Mourgos
Vargas 124 Mourgos
Zlotkey 100 King
Abel 149 Zlotkey
Taylor 149 Zlotkey
Grant 149 Zlotkey
Whalen 101 Kochhar
Hartstein 100 King
Fay 201 Hartstein
Higgins 101 Kochhar
Gietz 205 Higgins

Opmerking

De SELF JOIN komt sporadisch voor en is dus niet erg belangrijk. In de database die wij gebruiken is er slechts één SELF-JOIN te maken en die staat hierboven uitgelegd.

Equi join#

Een EQUIJOIN is een term voor een categorie join waarbij het is-gelijk-teken gebruikt wordt om twee of meerdere tabellen aan elkaar te knopen. Joins die hiertoe behoren zijn bijvoorbeeld de NATURAL JOIN, JOIN USING en JOIN ON met het = teken. Het is ook mogelijk twee tabellen samen te voegen met een vergelijking in de WHERE. Deze joins horen niet tot de ANSI-standaard maar ze worden ondersteund in elk Database Management System.

Voorbeeld van een EQUI JOIN met de vergelijking in de WHERE. Alle tabellen die je gebruikt komen op de WHERE regel.

SELECT employees.last_name, departments.department_name
FROM employees, departments
WHERE employees.department_id = departments.department_id; 
last_name department_name
King Executive
Kochhar Executive
De Haan Executive
Hunold IT
Ernst IT
Lorentz IT
Mourgos Shipping
Rajs Shipping
Davies Shipping
Matos Shipping
Vargas Shipping
Zlotkey Sales
Abel Sales
Taylor Sales
Whalen Administration
Hartstein Marketing
Fay Marketing
Higgins Accounting
Gietz Accounting

Voorbeelden van een EQUI JOIN met de vergelijking in de JOIN ON. De uitvoer is in beide gevallen exact hetzelfde.

SELECT employees.last_name, departments.department_name
FROM employees
 JOIN departments ON employees.department_id = departments.department_id;
last_name department_name
King Executive
Kochhar Executive
De Haan Executive
Hunold IT
Ernst IT
Lorentz IT
Mourgos Shipping
Rajs Shipping
Davies Shipping
Matos Shipping
Vargas Shipping
Zlotkey Sales
Abel Sales
Taylor Sales
Whalen Administration
Hartstein Marketing
Fay Marketing
Higgins Accounting
Gietz Accounting

Tip

Maar met een vergelijking in de WHERE kun je dus geen rijen tonen waarvan een van de kolommen NULL is. Met een LEFT JOIN ON kan dat wel en daarom is het verstandig jezelf aan te leren dat je altijd LEFT JOIN ON gebruikt.

Gebruik onderstaande query in plaats van de query met de vergelijking in de WHERE hierboven. Grant heeft geen department_name maar hij komt toch op het overzicht.

SELECT last_name, department_name
FROM employees 
  LEFT JOIN departments ON employees.department_id = departments.department_id;
last_name department_name
King Executive
Kochhar Executive
De Haan Executive
Hunold IT
Ernst IT
Lorentz IT
Mourgos Shipping
Rajs Shipping
Davies Shipping
Matos Shipping
Vargas Shipping
Zlotkey Sales
Abel Sales
Taylor Sales
Grant
Whalen Administration
Hartstein Marketing
Fay Marketing
Higgins Accounting
Gietz Accounting