Joins och relationer

Joins är limmet som binder ihop tabellerna. Utan dem sitter du fast med fragment av information – med dem får du en helhetsbild.

TL;DR

  • INNER JOIN – matcha rader där båda tabellerna har träff.
  • LEFT JOIN – behåll allt från vänster tabell, även om höger saknar motsvarighet.
  • RIGHT/FULL JOIN – spegelvända varianter (mindre vanliga i vardagen men bra att känna till).
  • Använd alias (s, o) för att hålla frågan lättläst.

Varför JOIN?

I relationsdatabaser sparas data i separata tabeller för att undvika upprepning. JOIN låter dig kombinera data från dessa tabeller baserat på relationer mellan dem.

Exempeldata

Vi använder dessa tabeller i alla exempel:

Students:

StudentIdFirstNameLastName
1AnnaSvensson
2BengtLarsson
3CeciliaNilsson
4DavidEriksson

Enrollments:

EnrollmentIdStudentIdCourseCode
11PRG101
21MAT101
32PRG101
42ENG101
53MAT101

Observera: David (StudentId 4) har inga kurser registrerade.

INNER JOIN – endast matchningar

INNER JOIN returnerar bara de rader där det finns en matchning i båda tabellerna. Detta är den vanligaste typen av JOIN.

SELECT s.StudentId, s.FirstName, e.CourseCode
FROM Students AS s
INNER JOIN Enrollments AS e ON s.StudentId = e.StudentId;

Resultat:

StudentIdFirstNameCourseCode
1AnnaPRG101
1AnnaMAT101
2BengtPRG101
2BengtENG101
3CeciliaMAT101

Förklaring: Endast studenter som har kurser visas. David saknas eftersom han inte har någon rad i Enrollments. Anna och Bengt får flera rader eftersom de har flera kurser.

LEFT JOIN – behåll allt från vänster

LEFT JOIN returnerar alla rader från vänster tabell (Students), även om det inte finns matchningar i höger tabell (Enrollments). Saknade värden fylls med NULL.

SELECT s.StudentId, s.FirstName, e.CourseCode
FROM Students AS s
LEFT JOIN Enrollments AS e ON s.StudentId = e.StudentId
ORDER BY s.StudentId;

Resultat:

StudentIdFirstNameCourseCode
1AnnaPRG101
1AnnaMAT101
2BengtPRG101
2BengtENG101
3CeciliaMAT101
4DavidNULL

Förklaring: Alla studenter visas, inklusive David. Eftersom David inte har några kurser får CourseCode värdet NULL för honom. Detta är användbart för att hitta “saknar”-relationer.

Hitta “saknar”-relationer med LEFT JOIN

En av de kraftfullaste användningarna av LEFT JOIN är att hitta rader som saknar en relation.

-- Hitta studenter som inte har några kurser
SELECT s.StudentId, s.FirstName, s.LastName
FROM Students AS s
LEFT JOIN Enrollments AS e ON s.StudentId = e.StudentId
WHERE e.EnrollmentId IS NULL;

Resultat:

StudentIdFirstNameLastName
4DavidEriksson

Förklaring: LEFT JOIN ger David en rad med NULL i Enrollments-kolumnerna. WHERE-villkoret e.EnrollmentId IS NULL filtrerar fram endast de studenter som saknar enrollments.

RIGHT och FULL JOIN

RIGHT JOIN är spegelvändningen av LEFT JOIN – den behåller alla rader från höger tabell:

-- RIGHT JOIN (stöds inte i SQLite, men fungerar i MySQL/SQL Server)
SELECT s.FirstName, e.CourseCode
FROM Students AS s
RIGHT JOIN Enrollments AS e ON s.StudentId = e.StudentId;

Detta skulle visa alla enrollments, även om det finns orphaned enrollments utan student.

FULL OUTER JOIN (PostgreSQL, SQL Server) behåller rader från båda tabellerna, även om matchning saknas. SQLite stödjer inte detta direkt, men det kan återskapas med UNION.

CROSS JOIN – kartesisk produkt

CROSS JOIN skapar alla möjliga kombinationer mellan två tabeller.

Exempeldata - Courses:

CourseCodeCourseName
PRG101Programmering
MAT101Matematik
SELECT s.FirstName, c.CourseName
FROM Students AS s
CROSS JOIN Courses AS c
WHERE s.StudentId <= 2;  -- Begränsa för läsbarhet

Resultat:

FirstNameCourseName
AnnaProgrammering
AnnaMatematik
BengtProgrammering
BengtMatematik

Förklaring: Varje student kopplas till varje kurs, totalt 2 studenter × 2 kurser = 4 rader. Använd med försiktighet – stora tabeller kan ge enorma resultat!

Self JOIN – jämföra inom samma tabell

Self JOIN används när en tabell refererar till sig själv, till exempel för hierarkier.

Exempeldata - Employees:

EmployeeIdEmployeeNameMentorId
1AliceNULL
2Bob1
3Charlie1
4Diana2
SELECT
    mentor.EmployeeName AS Mentor,
    mentee.EmployeeName AS Mentee
FROM Employees AS mentor
INNER JOIN Employees AS mentee ON mentor.EmployeeId = mentee.MentorId;

Resultat:

MentorMentee
AliceBob
AliceCharlie
BobDiana

Förklaring: Samma tabell används två gånger med olika alias (mentor, mentee). Vi kopplar mentorer till deras mentees via MentorId.

JOIN med GROUP BY – kraftfulla rapporter

Kombinationen av JOIN och GROUP BY är perfekt för sammanfattningar.

SELECT
    s.StudentId,
    s.FirstName,
    COUNT(e.EnrollmentId) AS CourseCount
FROM Students AS s
LEFT JOIN Enrollments AS e ON s.StudentId = e.StudentId
GROUP BY s.StudentId, s.FirstName
ORDER BY CourseCount DESC;

Resultat:

StudentIdFirstNameCourseCount
1Anna2
2Bengt2
3Cecilia1
4David0

Förklaring: LEFT JOIN säkerställer att alla studenter inkluderas. GROUP BY grupperar per student, och COUNT() räknar deras kurser. David får 0 eftersom han saknar kurser.

Tips & best practices

  • Indexera foreign key-kolumnen (Enrollments.StudentId).
  • Använd tydliga alias (Students AS s).
  • Filtrera i ON när du vill påverka joinen, i WHERE när du vill filtrera efter join.
  • Undvik SELECT * i produktion – välj kolumner explicit.

Vanliga fallgropar

  • Dubblerade rader: kontrollera att du inte joinar på en 1:N relation utan att använda DISTINCT/GROUP BY när du bara vill ha unika.
  • NULL-problem: WHERE e.CourseCode IS NOT NULL efter en LEFT JOIN tar bort vänster-rader – flytta filtret till ON.
  • Fel alias: små stavfel i alias leder snabbt till “ambiguous column”-fel.

Sammanfattning

JOIN är fundamentalt för att arbeta med relationsdatabaser:

  • INNER JOIN – visa endast matchningar mellan tabeller
  • LEFT JOIN – behåll alla från vänster, fyll höger med NULL om saknas
  • RIGHT JOIN – behåll alla från höger (omvänd LEFT JOIN)
  • CROSS JOIN – alla kombinationer (kartesisk produkt)
  • Self JOIN – koppla tabell till sig själv för hierarkier

Kom ihåg:

  1. Använd tydliga alias (s, e, c) för läsbarhet
  2. Indexera foreign key-kolumner för prestanda
  3. LEFT JOIN + WHERE NULL = hitta “saknar”-relationer
  4. Kombinera med GROUP BY för rapporter

ON vs WHERE vid JOIN:

  • ON – styr vilka rader som joinas
  • WHERE – filtrerar resultatet efter join

Dad joke

Varför gillar databasen parmiddagar?

För att den får joina två tabeller åt gången.


Upp

Upp


Licens: Apache 2.0 | © 2023 Marcus Medina, Campus Mölndal. Alla rättigheter förbehållna.
Du får använda och modifiera detta verk enligt villkoren i Apache License, Version 2.0. Du får inte använda detta verk för kommersiella ändamål utan tillstånd från upphovsmannen.