SELECT 3: JOINS

30 Januar 2015

Med SQL-kommandoen SELECT kan vi plukka ut data frå ein enkelt tabell i henhold til visse kriterier. Men vi kan også kobla to eller fleire tabellar og visa resultatet av det. Dette kallast på databasespråk for JOINS. Vi skal sjå korleis vi kan gjera dette.

Tar igjen utgangspunkt i vår enkle bokdatabase (den enklaste versjonen der det bare kan vera ein forfattar for ei bok) der vi bare har to tabellar: ein forfattar-tabell og ein bok-tabell. For å få fram forskjellane på ulike joins utvidar eg den bittelitt. Ny forfattar er Albert Camus, og ny bok er Enûma Eliš.

Forfattar (tabell)

FNR Fnavn Enavn Diverse info
1 Jarle Rasmussen forfattar, lærar og prest
2 Jon Severud skriv om underklassen
3 Gunnar Øyro artig, men lite produktiv
4 Albert Camus fransk forfattar og filosof

Bok (tabell)

BNR Tittel Forfattarnr
1 To henrettelser*
1
2 Alt flyter
1
3 Ubehaget i skolen 2
4 Ei Gjenreise 2
5 Fandens ordbok 3
6 Enûma Elis NULL

(* Titlane er noko forkorta! ) Merk at eg her tilllet at bøker ikkje har ein forfattar (kanskje han er ukjent?), og vi har forfattarar som ikkje har bøker i databasen (kanskje disse ikkje er kjøpt inn endå?). Den nye forfattaren Albert Camus er ikkje referert til i boktabellen, og den nye boka Enûma Eliš har ingen (kjent) forfattar. Merk at her bruker vi verdien NULL for å fortelja at det manglar data. Det er altså ikkje det same som 0! Datamodellen vår ser slik ut:

biliotekdatabase

1 Inner Join

Anta at vi vil ha ut ei bokliste med tittelen på boka og navnet på forfattaren. Dette vil vi ha for alle bøkene i databasen bortsett frå dei som ikkje har ein forfattar. Dette kan vi gjera vha eit såkalt Inner Join. Syntaks er slik:

SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name = table2.column_name;

For oss koker dette ned til:

SELECT bok.tittel, forfattar.Fnavn, forfattar.Enavn
FROM forfattar
JOIN bok
ON forfattar.FNR = bok.forfattarnr;

Her har vi satt forfattar som tabell1 og bok som tabell2. Men i dette tilfellet kunne vi gjort omvendt. Merk at vi må ha med betingelsen ON. Vi får no ut bare dei bøkene med et forfattarnr som fins i begge tabellane. Dette er det same som å ta ut snittet mellom forfattanr i tabell1 og tabell2. Vi kan beskriva dette med Venndiagram slik:

Join

Resultatet av denne spørringen blir då:

tittel			Fnavn	Enavn
To henrettelser Jarle Rasmussen
Alt flyter Jarle Rasmussen
Ubehaget i skolen Jon Severud
Ei Gjenreise Jon Severud
Fandens ordbok Gunnar Øyro

2 Right Join

Sett at vi også vil ha ut dei bøkene som ikkj har forfattar. Dette svarar til eit Right Join. Då tar vi med forfattarnr som er NULL (?) eller ikkje fins i forfattar-tabellen. Syntaksen er det samme, bare at vi skriv RIGHT JOIN i staden for JOIN. (Somme databaser bruker RIGHT OUTER JOIN)


SELECT bok.tittel, forfattar.Fnavn, forfattar.Enavn
FROM forfattar
RIGHT JOIN bok
ON forfattar.FNR = bok.forfattarnr;

Dette kan vi beskriva slik: (husk at bok er tabell2, dvs. den til høgre)

Right Join

Resultatet er no identisk med i stad bortsett frå ei ny linje:

Enûma Elis    NULL    NULL

3 Left Join

Til slutt skal vi sjå på korleis vi kan lista ut alle forfattarar med eventuelle bøker. Vi tar altså med dei som ikkje har registert bok i boktabellen. Dette kan vi gjera med eit Left Join slik:


SELECT bok.tittel, forfattar.Fnavn, forfattar.Enavn
FROM forfattar
LEFT JOIN bok
ON forfattar.FNR = bok.forfattarnr;

Tilsvarande Venndiagram: (husk at forfattar er tabell1, dvs. den til venstre)
Left Join
Resultatet er igjen som et Inner Join (eksempel 1) bortsett frå den ekstra linja:

NULL    Albert Camus 

Det fins også noko som heiter FULL OUTER JOIN, men det ser ikkje ut til at det er støtta av ein egen kommando. I staden kan det gjerast vha kommandoen UNION. I praksis gjer ein gjer eit LEFT JOIN og eit RIGHT JOIN, og så slå saman disse vha UNION. Resultatet blir då at begge dei to ekstra linjene kjem med.

LENKER

Denne gir ein ganske god innføring: http://www.sitepoint.com/understanding-sql-joins-mysql-database/ ..