You are on page 1of 85

Joins

SQL

1
Inhoud

❖Relaties
❖Zoeken in 2 tabellen
– INNER JOIN
– LEFT OUTER JOIN
– RIGHT OUTER JOIN
– FULL OUTER JOIN
❖Aanpassen van kolomdefinitie
❖Zoeken in 3 of meer tabellen
❖Aliassen gebruiken voor kolommen en
tabellen
2
Relaties

3
Huidige situatie

⚫ Tot nu toe hebben we altijd al onze informatie uit


één tabel gehaald.

⚫ Het hele idee achter een relationele databank is


dat de relaties tussen verschillende tabellen
belangrijk zijn.

⚫ Relatie: voorgesteld door een lijn in het


datamodel.

*
Boete Speler
1 4
Relaties

⚫ Tussen de tabellen zijn er koppelingen of relaties

⚫ Een relatie tussen twee groepen wordt gelegd op


basis van de primaire sleutel (PK) van één groep
en de refererende sleutel (FK) van een andere
groep. PK FK

⚫ We stellen de relaties grafisch voor in een


relationeel diagram.

5
Bij elke boete slaan we het spelerId op.

Relaties Dit verwijst naar de kolom "id" uit de tabel Speler


Elke boete is van één speler
Je kan maar één spelerId invullen bij een
boete.
Een speler kan meerdere boetes krijgen
Bij verschillende boetes kunnen dezelfde
spelerId’s ingevuld worden.

6
Relaties

⚫ Elke relatie heeft een aard en connectiviteit

⚫ 1..1 (aard = 1, connectiviteit = 1)


⚫ 0..* (aard = 0, connectiviteit = *)

1..1
Klant Order
0..*

7
Relaties (aard...connectiviteit)
⚫ de aard van een relatie:

– De aard van een relatie kan optioneel of verplicht


zijn
– De entiteit mag of moet aanwezig zijn
– Mogelijkheden:

– Een klant kan bestaan zonder orders (0)


– Een order moet aan een klant gekoppeld worden (1)
8
Relaties (aard...connectiviteit)

⚫ de connectiviteit van een relatie:

– De connectiviteit geeft weer hoeveel voorkomens er


overeenkomen met een bepaald voorkomen uit de
andere groep

– De connectiviteit wordt in het grafisch model


weergegeven d.m.v.
• 1 (betekenis: komt één keer voor )
• en het symbool “*” (betekenis: komt veel keer voor)

9
Connectiviteit

⚫ Soorten relaties:
– Eén op één relatie
– Eén op veel relatie
– Veel op één relatie
– Veel op veel relatie

10
Connectiviteit

⚫ Eén op één relatie

• Eén student heeft één studiebeurs


• Deze studiebeurs is uniek voor deze student

1 1
Student Studiebeurs

11
Connectiviteit
⚫ Eén op veel relatie

• In één klas mogen meerdere studenten


zitten
• Eén student zit in één klas

1
Klas Student

*
Men beschrijft eerst de relatie van links naar
rechts.

12
Connectiviteit

⚫ Eén op veel relatie

• In één klas mogen meerdere studenten


zitten
• Eén student zit in één klas
1
Klas Student
*
Nadien beschrijft je de relatie van rechts naar links.

13
Connectiviteit

⚫ Veel op één relatie

• Eén student zit in één klas


• In één klas mogen meerdere studenten
zitten

Student * Klas
1

14
Connectiviteit

⚫ Veel op één relatie

• Eén student zit in één klas


• In één klas mogen meerdere studenten
zitten

Student * Klas
1

15
Connectiviteit

⚫ Veel op veel relatie

• Elke student krijgt les van meerdere


docenten
• Elke docent geeft les aan meerdere
studenten

Student * Docent
*

16
Connectiviteit

⚫ Veel op veel relatie

• Elke student krijgt les van meerdere docenten


• Elke docent geeft les aan meerdere
studenten

Student * Docent
*
Deze relatie komt NOOIT voor in een ERD.
Later volgt de oplossing !

17
Relaties

⚫ Een relatie geldt steeds in twee richtingen. Voor


beide richtingen moeten aard en connectiviteit
nagegaan worden.
– 1ste cijfer = aard
– 2de cijfer = connectiviteit

⚫ De combinatie 1..1 wordt dikwijls afgekort naar 1


⚫ De combinatie 0..* wordt dikwijls afgekort naar *

18
Refererende sleutel of Foreign Key (FK)

⚫ Een refererende sleutel is een veld of een


combinatie van velden uit een tabel waarvan de
waarden moeten overeenstemmen met de
waarden van de primaire sleutel van een andere
tabel

19
Refererende sleutel of Foreign Key (FK)

⚫ Voorbeeld:
– Elk order wordt geplaatst door 1 klant
– Een klant heeft meerdere orders
– Dus er is een relatie tussen entiteiten

⚫ We slaan die relatie op door de entiteiten te doen


verwijzen

⚫ Hiervoor gebruiken we een Foreign Key (FK)


(hier: klantId)

20
ERD voorbeeld – H&S

Klant Order

Product

21
ERD voorbeeld – H&S
(verplicht aanwezig – 1 exemplaar)

1..1
Klant Order

1..1

Product

22
ERD voorbeeld – H&S
# orders (optioneel – veel exemplaren)

1..1
Klant Order
0..*

0..*

Product

23
ERD voorbeeld – H&S
# orders (optioneel – veel exemplaren)

1..1
Klant Order
0..*

Klant Order
id PK id PK
familienaam klantId FK
voornaam

24
Associatie-entiteit?
Order 0..* Product
0..*

⚫ Geeft een M op N koppeling weer tussen


twee of meerdere entiteiten.
⚫ Bv:
– In een order zitten meerdere producten
– Een product komt voor in meerdere orders
⚫ Aan beide zijden een * ?

25
Associatie-entiteit?

⚫ Geeft een M op N koppeling weer tussen


twee of meerdere entiteiten.
⚫ Bv:
– In een order zitten meerdere producten
– Een product komt voor in meerdere orders
⚫ Oplossing:
– Er wordt een associatie-entiteit Orderlijn
toegevoegd
– En de veel op veel relatie wordt omgevormd naar
een 1 op veel relatie
26
Voorbeeld – H&S

⚫ Wat zijn de attributen van de kernentiteit


Orderlijn?

Orderlijn
id PK
orderId FK
productId FK
hoeveelheid

⚫ Orderlijn is een associatie-entiteit tussen Order en


Product
– Op een order kunnen meerdere producten staan
– Een product kan op meerdere orders voorkomen
27
Associatie- entiteit?

1..1
Order Orderlijn
0..*
0..*
1..1 op 0..veel
0..veel op 1..1
1..1 op 0..*
0..* op 1 ..1
1..1

Product

28
ERD voorbeeld – H&S

1..1
Order Orderlijn
0..*
0..* 0..*

1..1 1..1

Klant Product

29
Zoeken in 2 tabellen

30
Voorbeeld

⚫ Welke spelers (naam) hebben boetes gekregen?


SELECT *
FROM Tennis.Boete
ORDER BY spelerId;

– Wie is speler 6, 8, 27, 44 en 104 ?


31
Beter voorbeeld

⚫ Welke spelers (naam) hebben boetes gekregen?

– De informatie komt nu uit 2 tabellen nl. Boete en


Speler
32
Beter voorbeeld
⚫ Boete:
SELECT
id,
spelerId,
datum,
bedrag
FROM Tennis.Boete

⚫ Speler:
SELECT
id,
CONCAT(TRIM(voornaam),SPACE(1),TRIM(naam)) AS 'naam',
straat,
huisnummer,
postcode,
plaats
FROM Tennis.Speler
WHERE id IN (6, 8, 27, 44, 104)
ORDER BY id; 33
Beter voorbeeld

⚫ We hebben twee tabellen nodig om de informatie


te kunnen presenteren.
– Boete
– Speler
⚫ Mogelijke SQL-instructie:
SELECT Resultaat:
Speler.*,
Boete.* 8 (boetes) * 15 (spelers) = 120 rijen
FROM
Tennis.Speler, Dit is bijna nooit de bedoeling !!!
Tennis.Boete

34
Oplossing Join

⚫ Alleen de gegevens tonen waar Speler.id (PK) =


Boete.spelerId (FK)
SELECT
Speler.id,
CONCAT(TRIM(Speler.voornaam),SPACE(1),TRIM(Speler.naam))
AS 'naam',
Boete.datum,
Boete.bedrag
FROM

Tennis.Speler INNER JOIN Tennis.Boete


ON Speler.id = Boete.spelerId
;

➢ Alleen de spelers die in beide tabellen voorkomen, komen in het


resultaat. Spelers die geen boetes hebben, komen niet in het 35
resultaat.
JOINS
⚫ Welke spelers (naam) hebben boetes gekregen?

PK

FK
Speler.id = Boete.spelerId

➔ Join-voorwaarde
36
Joins Speler
Spelers
zonder
boetes
Spelers met boetes

2
7 Boete
28
39 6
100 8
112 27
… 44
104
Niet in ons
voorbeeld

37
Joins

⚫ Waarom komt speler 44 meerdere keren voor ?


⚫ Waar zijn de spelers 2, 7, 8, enz. ?
38
Joins

⚫ Speler 44 heeft meerdere boetes en staat daarom


meerdere keren in het resultaat
– Dit kunnen we alleen vermijden door records
te groeperen → Zie later

⚫ Spelers 2, 7, 8 ... hebben geen enkele boete en


vallen dus weg uit de lijst
– Oplossing: LEFT of RIGHT OUTER JOIN (later)

39
Ander voorbeeld : INNER JOIN

⚫ Tabel Les.Land

PK

⚫ Tabel Les.Staat

PK FK
40
Ander voorbeeld : INNER JOIN
Land Land
zonder
staat
Land met staten

id
Staat
3
landId
1
2
id
4

Staat zonder land


41
Ander voorbeeld : INNER JOIN

⚫ Geef enkel de landen die een staat hebben?


Les.Land Les.Staat

SELECT *
FROM
Les.Land INNER JOIN Les.Staat
ON Land.id = Staat.landId Resultaat

42
Aanpassen van kolom-definitie

Spelers Speler
zonder
boetes Spelers met boetes

2
7
28
39 Boete
100 6
112 8
… 27
44
104
Boete 10 – speler
NULL toevoegen
43
Aanpassen van kolom-definitie

⚫ De tennisclub ontvangt een boete van 25€


(05-03-2019) maar deze boete is nog niet
toegekend aan een speler.

44
Aanpassen van kolom-definitie

⚫ We moeten kolom spelerId wijzigen van


NOT NULL ALLOW (NNA) naar NULL ALLOW (NA)

45
Aanpassen van kolom-definitie

⚫ Syntax:

ALTER TABLE tabelnaam


ALTER COLUMN kolomnaam datatype [NOT NULL];

⚫ Voorbeeld:

ALTER TABLE Tennis.Boete


ALTER COLUMN spelerId int NULL;

of

ALTER TABLE Tennis.Boete


ALTER COLUMN spelerId int; 46
Ontvangen van een nieuwe
boete
⚫ De tennisclub ontvangt een boete maar deze
boete is nog niet toegekend aan een speler.
INSERT INTO Tennis.Boete
VALUES (NULL,'2019-03-05',25);

47
Joins Speler
Spelers
zonder
boetes
Spelers met boetes

2
7 Boete
28
39 6
100 8
112 27
… 44
104
NULL,’2019-03-05',25

Boete die nog niet is


toegekend aan een
speler
48
Soorten Joins

⚫ (INNER) JOIN : Retourneert records met overeenkomende


waarden in beide tabellen
⚫ LEFT (OUTER) JOIN : Retourneer alle records uit de
linkertabel en de overeenkomende records uit de rechtse tabel
⚫ RIGHT (OUTER) JOIN : Retourneer alle records van de
rechtse tabel en de overeenkomende records uit de linker tabel
⚫ FULL (OUTER) JOIN : Retourneer alle records wanneer er
een overeenkomst is in de linker- of rechtentabel

49
Soorten Joins

⚫ Spelers zonder boete


⚫ Boetes niet toegekend aan een speler (logisch?)
⚫ Spelers met hun boete

50
Soorten Joins

⚫ Gevraagd:
– Spelers met hun boete

SELECT
Speler.id,
CONCAT(TRIM(Speler.voornaam),SPACE(1),TRIM(Speler.naam))
AS 'naam’,
Boete.datum,
Boete.bedrag
FROM
Tennis.Speler INNER JOIN Tennis.Boete
ON Speler.id = Boete.spelerId
;

51
Join: INNER JOIN

⚫ Syntax:
SELECT
kolomnaam1,
kolomnaam2,…
FROM
Schema.Tabel1 INNER JOIN Schema.Tabel2
ON Tabel1.kolomnaam = Tabel2.kolomnaam
;

52
Soorten Joins

⚫ Gevraagd:
– Spelers zonder boete
SELECT
Speler.id,
CONCAT(TRIM(Speler.voornaam),SPACE(1),TRIM(Speler.naam))
AS 'naam’,
Boete.datum,
Boete.bedrag
FROM
Tennis.Speler LEFT JOIN Tennis.Boete
ON Speler.id = Boete.spelerId
;

53
Soorten Joins

⚫ Gevraagd:
– Spelers zonder boete

⚫ Oplossing ≠ gevraagde
⚫ Oplossing = spelers met
hun eventuele boetes

54
Join: LEFT [OUTER] JOIN

⚫ Syntax:
SELECT
kolomnaam1,
kolomnaam2,…
FROM
Schema.Tabel1 LEFT [OUTER] JOIN Schema.Tabel2
ON Tabel1.kolomnaam = Tabel2.kolomnaam
;

55
Ander voorbeeld : LEFT JOIN

⚫ Geef alle landen met hun eventuele staat?


Land Staat

SELECT *
FROM
Les.Land LEFT JOIN Les.Staat
ON Land.id = Staat.landId
;
56
Soorten Joins

⚫ Spelers zonder boete


SELECT
Speler.id,
CONCAT(TRIM(Speler.voornaam),SPACE(1),TRIM(Speler.naam))
AS 'naam’,
Boete.datum,
Boete.bedrag
FROM
Tennis.Speler LEFT JOIN Tennis.Boete
ON Speler.id = Boete.spelerId
WHERE Boete.bedrag IS NULL;

⚫ Oplossing = gevraagde
57
Soorten Joins

⚫ Boetes niet toegekend aan een speler


SELECT
Speler.id,
CONCAT(TRIM(Speler.voornaam),SPACE(1),TRIM(Speler.naam))
AS 'naam’,
Boete.datum,
Boete.bedrag
FROM
Tennis.Speler RIGHT JOIN Tennis.Boete
ON Speler.id = Boete.spelerId
;

58
Soorten Joins

⚫ Boetes niet toegekend aan een speler

⚫ Oplossing ≠ gevraagde
⚫ Oplossing = boetes met de eventuele toegekende
spelers
59
Join: RIGHT OUTER JOIN

⚫ Syntax:
SELECT
kolomnaam1,
kolomnaam2,…
FROM
Schema.Tabel1 RIGHT [OUTER] JOIN Schema.Tabel2
ON Tabel1.kolomnaam = Tabel2.kolomnaam
;

60
Ander voorbeeld : RIGHT JOIN

⚫ Geef alle staten met hun eventuele landen?


Land Staat

SELECT *
FROM
Les.Land RIGHT JOIN Les.Staat
ON Land.id = Staat.landId
;
61
Soorten Joins

⚫ Boetes niet toegekend aan een speler


SELECT
Speler.id,
CONCAT(TRIM(Speler.voornaam),SPACE(1),TRIM(Speler.naam))
AS 'naam',
Boete.datum,
Boete.bedrag
FROM
Tennis.Speler RIGHT JOIN Tennis.Boete
ON Speler.id = Boete.spelerId
WHERE Speler.naam IS NULL;

⚫ Oplossing = gevraagde
⚫ Oplossing = boetes niet toegekend aan een speler
62
Soorten Joins

⚫ Alle spelers en alle boetes


SELECT
Speler.id,
CONCAT(TRIM(Speler.voornaam),SPACE(1),TRIM(Speler.naam))
AS 'naam',
Boete.datum,
Boete.bedrag
FROM
Tennis.Speler FULL OUTER JOIN Tennis.Boete
ON Speler.id = Boete.spelerId
;

63
Soorten Joins

⚫ Alle spelers en alle boetes

64
Join: FULL OUTER JOIN

⚫ Syntax:
SELECT
kolomnaam1,
kolomnaam2,…
FROM
Schema.Tabel1 FULL [OUTER] JOIN Schema.Tabel2
ON Tabel1.kolomnaam = Tabel2.kolomnaam
;

65
Ander voorbeeld : FULL JOIN

⚫ Geef alle landen en alle staten?

❖Zoeken in 3 of meer tabellen

SELECT *
FROM
Les.Land FULL JOIN Les.Staat
ON Land.id = Staat.landId
;
66
Zoeken in 3 of meer
tabellen

67
Voorbeelden

⚫ Geef voor elke speler al zijn wedstrijden en het team


waarvoor hij de wedstrijd speelde?
– Begin met de tabel waar je alle records van wilt.
– Welke?
• Speler

68
Voorbeelden

⚫ Geef voor elke speler al zijn wedstrijden en het team


waarvoor hij de wedstrijd speelde?
– Volg de relatie om de andere tabellen eraan te
koppelen.
• 1ste join: Speler en Wedstrijd

69
Voorbeelden: 1STE JOIN
Speler - Wedstrijd

PK

FK

Speler.id =
Wedstrijd.spelerId

70
Voorbeelden

⚫ Geef voor elke speler al zijn wedstrijden en het


team waarvoor hij de wedstrijd speelde?
– Volg de relatie om de andere tabellen eraan te
koppelen.
• 1ste join: Speler en Wedstrijd
• 2de join: Wedstrijd en Team

71
Voorbeelden: 2de JOIN
Wedstrijd met Team

PK

FK FK

Speler.id =
Wedstrijd.spelerId
PK
Wedstrijd.teamId =
Team.id 72
1ste join:
Speler en Wedstrijd vastleggen

SELECT
Speler.id,
Speler.naam,
Wedstrijd.id AS 'wedstrijd',
Wedstrijd.aantalGewonnenSets,
Wedstrijd.aantalVerlorenSets
FROM
Tennis.Speler INNER JOIN Tennis.Wedstrijd
ON Speler.id = Wedstrijd.spelerId
;

73
2de join:
resultaat van 1ste join en Team vastleggen
SELECT
Speler.id,
Speler.naam,
Wedstrijd.id AS 'wedstrijd',
Wedstrijd.aantalGewonnenSets,
Wedstrijd.aantalVerlorenSets,
Team.id AS 'team',
Team.divisie
FROM

Tennis.Speler INNER JOIN Tennis.Wedstrijd


ON Speler.id = Wedstrijd.spelerId

INNER JOIN Tennis.Team


ON Wedstrijd.teamId = Team.id
;

74
2de join:
resultaat van 1ste join en Team vastleggen

SELECT
Speler.id,
Speler.naam,
Wedstrijd.id AS 'wedstrijd',
Wedstrijd.aantalGewonnenSets,
Wedstrijd.aantalVerlorenSets,
Team.id AS 'team',
Team.divisie
FROM
Tennis.Speler INNER JOIN Tennis.Wedstrijd
ON Speler.id = Wedstrijd.spelerId
INNER JOIN Tennis.Team
ON Wedstrijd.teamId = Team.id
;

75
2de join:
resultaat van 1ste join en Team vastleggen

⚫ Rood = 1ste JOIN


⚫ Blauw = rood + 2de JOIN 76
INNER Joins
minstens tussen 3 tabellen
⚫ Syntax:

SELECT
kolomnaam1,
kolomnaam2,…
FROM
Tabel1 INNER JOIN Tabel2
ON Tabel1.kolomnaam = Tabel2.kolomnaam
INNER JOIN Tabel3
ON Tabel2.kolomnaam = Tabel3.kolomnaam
;

77
Voorbeelden

⚫ Hetzelfde als voorheen, maar ik wil alle spelers


SELECT
Speler.id,
Speler.naam,
Wedstrijd.id AS 'wedstrijd',
Wedstrijd.aantalGewonnenSets,
Wedstrijd.aantalVerlorenSets,
Team.id AS 'team',
Team.divisie
FROM
Tennis.Speler LEFT JOIN Tennis.Wedstrijd
ON Speler.id = Wedstrijd.spelerId
LEFT JOIN Tennis.Team
ON Wedstrijd.teamId = Team.id
);

78
Voorbeelden

⚫ Hetzelfde als voorheen, maar ik wil alle spelers

79
Voorbeelden

⚫ Merk op:
– Spelers die meerdere wedstrijden speelden
staan meerdere keren in de lijst
– Bij spelers die geen wedstrijd speelden wordt
alles opgevuld met NULL-waarden

80
Alias gebruiken

⚫ Kolom hernoemen
– Wedstrijd.id AS 'wedstrijd’
⚫ Tabelnaam hernoemen
– FROM Tennis.Speler AS S
– achter de tabelnaam schrijf je AS en 1, 2 of 3
letters, waarmee je weet over welke tabel het
gaat
– Afspraak:
• 1ste letter van de eigenlijke tabelnaam +
eventueel volgnummer (vb. zie later)
• Of 1ste letter van elk zelfstandig naamwoord
– WerknemerBedrijfJob wordt WBJ 81
Alias gebruiken
SELECT
S.id,
S.naam,
W.id AS 'wedstrijd’,
W.aantalGewonnenSets,
W.aantalVerlorenSets,
T.id AS 'team’,
T.divisie
FROM
Tennis.Speler AS S LEFT JOIN Tennis.Wedstrijd AS W
ON S.id = W.spelerId
LEFT JOIN Tennis.Team AS T
ON W.teamId = T.id
);

82
Voorbeelden

⚫ Hetzelfde als voorheen, maar ik wil de naam van


de aanvoerder van het team

83
Voorbeelden
SELECT
S1.id,
S1.naam,
W.id AS 'wedstrijd’,
W.aantalGewonnenSets,
W.aantalVerlorenSets,
T.id AS 'team’,
T.divisie,
S2.id,
S2.naam
FROM
Tennis.Speler AS S1 LEFT JOIN Tennis.Wedstrijd AS W
ON S1.id = W.spelerId
LEFT JOIN Tennis.Team AS T
ON W.teamId = T.id
LEFT JOIN Tennis.Speler AS S2
ON T.spelerId = S2.id
;

84
Oefeningen

85

You might also like