MySQL Forbind: Indre, Ydre, Venstre, Højre, Kryds
⚡ Smart opsummering
MySQL JOINS kombinerer rækker fra to eller flere relaterede tabeller til et enkelt resultatsæt. Denne ressource forklarer CROSS-, INNER-, LEFT-, RIGHT- og OUTER-JOINS med kørbare forespørgsler, eksempeldata og tydelige outputtabeller til praktisk databasearbejde.

Hvad er JOINS?
Joins hjælper med at hente data fra to eller flere databasetabeller.
Tabellerne er gensidigt relaterede ved hjælp af primære og fremmede nøgler.
Bemærk: JOIN er det mest misforståede emne blandt SQL-entusiaster. For enkelhedens skyld og for at lette forståelsen bruger vi en ny database til at øve os. Som vist nedenfor.
Alle eksempler nedenfor bruger disse to tabeller. film_id kolonne i medlemmer peger på id kolonne i film — den relation, som hver JOIN matcher på.
medlemmer
| id | fornavn | efternavn | film_id |
|---|---|---|---|
| 1 | Adam | Smith | 1 |
| 2 | Ravi | Kumar | 2 |
| 3 | Susan | Davidson | 5 |
| 4 | Jenny | Adrianna | 8 |
| 5 | Lee | Pong | 10 |
film
| id | titel | kategori |
|---|---|---|
| 1 | ASSASSIN'S CREED: EMBERS | Animationer |
| 2 | Ægte stål (2012) | Animationer |
| 3 | Alvin and the Chipmunks | Animationer |
| 4 | Tin Tins eventyr | Animationer |
| 5 | Sikker (2012) | Handling |
| 6 | Safe House (2012) | Handling |
| 7 | GIA | 18 + |
| 8 | Deadline 2009 | 18 + |
| 9 | Det beskidte billede | 18 + |
| 10 | Marley og mig | Romantik |
Hvorfor skal vi bruge JOINS?
Før vi ser på hver JOIN-type, er det værd at vide, hvorfor en JOIN foretrækkes frem for at køre flere forespørgsler.
Nu tænker du måske, hvorfor vi bruger JOINs, når vi kan udføre den samme opgave, der kører forespørgsler. Især hvis du har erfaring med databaseprogrammering, ved du, at vi kan køre forespørgsler én efter én, brug output fra hver i successive forespørgsler. Det er selvfølgelig muligt. Men ved at bruge JOINs kan du få arbejdet gjort ved kun at bruge en enkelt forespørgsel med alle søgeparametre. På den anden side MySQL kan opnå bedre ydeevne med JOINs, da den kan bruge indeksering. Blot brug af en enkelt JOIN-forespørgsel i stedet for at køre flere forespørgsler reducerer serveroverhead. Brug af flere forespørgsler i stedet, der fører til flere dataoverførsler imellem MySQL og applikationer (software). Yderligere kræver det også flere datamanipulationer i applikationsenden.
Det er klart, at vi kan opnå bedre MySQL og applikationsydelser ved brug af JOINs.
Typer af JOINS
MySQL understøtter adskillige JOIN-typer, der hver besvarer et forskelligt spørgsmål om de samme to tabeller. Tabellen nedenfor sammenligner dem; hver type demonstreres derefter med en forespørgsel og dens output.
| JOIN-type | Returnerede rækker | NULL'er i resultatet? | Typisk brug |
|---|---|---|---|
| KRÆS DETALJER | Hver række i tabel A er parret med hver række i tabel B | Ingen | Generering af alle mulige kombinationer |
| INNER JOIN | Kun rækker, der matcher betingelsen i begge tabeller | Ingen | Medlemmer, der rent faktisk lejede en film |
| LEFT JOIN | Alle rækker fra venstre tabel plus matches fra højre | Ja, på højre side | Alle film, selv dem der aldrig er lejet |
| HØJRE JOIN | Alle rækker fra højre tabel plus matches fra venstre | Ja, på venstre side | Alle film, selv uden tilknyttet medlem |
KRÆS DETALJER
Cross JOIN er en enkleste form for JOINs, som matcher hver række fra en databasetabel til alle rækker i en anden.
Med andre ord giver det os kombinationer af hver række i den første tabel med alle poster i den anden tabel.
Antag, at vi ønsker at få alle medlemsrekorder mod alle filmrekorder, kan vi bruge scriptet vist nedenfor for at få vores ønskede resultater.
SELECT * FROM `movies` CROSS JOIN `members`
Udførelse af ovenstående script i MySQL arbejdsbord giver os følgende resultater.
| id | title | id | first_name | last_name | movie_id | |
|---|---|---|---|---|---|---|
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 1 | Adam | Smith | 1 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 2 | Ravi | Kumar | 2 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 3 | Susan | Davidson | 5 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 4 | Jenny | Adrianna | 8 |
| 1 | ASSASSIN'S CREED: EMBERS | Animations | 6 | Lee | Pong | 10 |
| 2 | Real Steel(2012) | Animations | 1 | Adam | Smith | 1 |
| 2 | Real Steel(2012) | Animations | 2 | Ravi | Kumar | 2 |
| 2 | Real Steel(2012) | Animations | 3 | Susan | Davidson | 5 |
| 2 | Real Steel(2012) | Animations | 4 | Jenny | Adrianna | 8 |
| 2 | Real Steel(2012) | Animations | 6 | Lee | Pong | 10 |
| 3 | Alvin and the Chipmunks | Animations | 1 | Adam | Smith | 1 |
| 3 | Alvin and the Chipmunks | Animations | 2 | Ravi | Kumar | 2 |
| 3 | Alvin and the Chipmunks | Animations | 3 | Susan | Davidson | 5 |
| 3 | Alvin and the Chipmunks | Animations | 4 | Jenny | Adrianna | 8 |
| 3 | Alvin and the Chipmunks | Animations | 6 | Lee | Pong | 10 |
| 4 | The Adventures of Tin Tin | Animations | 1 | Adam | Smith | 1 |
| 4 | The Adventures of Tin Tin | Animations | 2 | Ravi | Kumar | 2 |
| 4 | The Adventures of Tin Tin | Animations | 3 | Susan | Davidson | 5 |
| 4 | The Adventures of Tin Tin | Animations | 4 | Jenny | Adrianna | 8 |
| 4 | The Adventures of Tin Tin | Animations | 6 | Lee | Pong | 10 |
| 5 | Safe (2012) | Action | 1 | Adam | Smith | 1 |
| 5 | Safe (2012) | Action | 2 | Ravi | Kumar | 2 |
| 5 | Safe (2012) | Action | 3 | Susan | Davidson | 5 |
| 5 | Safe (2012) | Action | 4 | Jenny | Adrianna | 8 |
| 5 | Safe (2012) | Action | 6 | Lee | Pong | 10 |
| 6 | Safe House(2012) | Action | 1 | Adam | Smith | 1 |
| 6 | Safe House(2012) | Action | 2 | Ravi | Kumar | 2 |
| 6 | Safe House(2012) | Action | 3 | Susan | Davidson | 5 |
| 6 | Safe House(2012) | Action | 4 | Jenny | Adrianna | 8 |
| 6 | Safe House(2012) | Action | 6 | Lee | Pong | 10 |
| 7 | GIA | 18+ | 1 | Adam | Smith | 1 |
| 7 | GIA | 18+ | 2 | Ravi | Kumar | 2 |
| 7 | GIA | 18+ | 3 | Susan | Davidson | 5 |
| 7 | GIA | 18+ | 4 | Jenny | Adrianna | 8 |
| 7 | GIA | 18+ | 6 | Lee | Pong | 10 |
| 8 | Deadline(2009) | 18+ | 1 | Adam | Smith | 1 |
| 8 | Deadline(2009) | 18+ | 2 | Ravi | Kumar | 2 |
| 8 | Deadline(2009) | 18+ | 3 | Susan | Davidson | 5 |
| 8 | Deadline(2009) | 18+ | 4 | Jenny | Adrianna | 8 |
| 8 | Deadline(2009) | 18+ | 6 | Lee | Pong | 10 |
| 9 | The Dirty Picture | 18+ | 1 | Adam | Smith | 1 |
| 9 | The Dirty Picture | 18+ | 2 | Ravi | Kumar | 2 |
| 9 | The Dirty Picture | 18+ | 3 | Susan | Davidson | 5 |
| 9 | The Dirty Picture | 18+ | 4 | Jenny | Adrianna | 8 |
| 9 | The Dirty Picture | 18+ | 6 | Lee | Pong | 10 |
| 10 | Marley and me | Romance | 1 | Adam | Smith | 1 |
| 10 | Marley and me | Romance | 2 | Ravi | Kumar | 2 |
| 10 | Marley and me | Romance | 3 | Susan | Davidson | 5 |
| 10 | Marley and me | Romance | 4 | Jenny | Adrianna | 8 |
| 10 | Marley and me | Romance | 6 | Lee | Pong | 10 |
INNER JOIN
En CROSS JOIN returnerer alle mulige parringer, hvilket sjældent er det, man ønsker. En INNER JOIN indsnævrer resultatet til de par, der rent faktisk er relaterede.
Den indre JOIN bruges til at returnere rækker fra begge tabeller, der opfylder den givne betingelse.
Antag, at du ønsker at få en liste over medlemmer, der har lejet film, sammen med titler på film, de har lejet. Du kan blot bruge en INNER JOIN til det, som returnerer rækker fra begge tabeller, der opfylder de givne betingelser.
SELECT members.`first_name` , members.`last_name` , movies.`title` FROM members ,movies WHERE movies.`id` = members.`movie_id`
Udførelse af ovenstående script give
| first_name | last_name | title |
|---|---|---|
| Adam | Smith | ASSASSIN'S CREED: EMBERS |
| Ravi | Kumar | Real Steel(2012) |
| Susan | Davidson | Safe (2012) |
| Jenny | Adrianna | Deadline(2009) |
| Lee | Pong | Marley and me |
Bemærk, at ovenstående resultatscript også kan skrives som følger for at opnå de samme resultater.
SELECT A.`first_name` , A.`last_name` , B.`title` FROM `members` AS A INNER JOIN `movies` AS B ON B.`id` = A.`movie_id`
Ydre JOINs
En INNER JOIN fjerner lydløst rækker, der ikke har nogen partner. Når disse ikke-matchede rækker er vigtige, er en OUTER JOIN det rigtige valg.
MySQL Outer JOINs returnerer alle matchende poster fra begge tabeller.
Det kan detektere poster, der ikke har nogen match i sammenføjet tabel. Det vender tilbage NULL værdier for poster i sammenføjet tabel, hvis der ikke findes noget match.
Lyder det forvirrende? Lad os se på et eksempel –
LEFT JOIN
Antag nu, at du ønsker at få titler på alle film sammen med navne på medlemmer, der har lejet dem. Det er klart, at nogle film ikke er blevet lejet af nogen. Vi kan simpelthen bruge LEFT JOIN til formålet.
LEFT JOIN returnerer alle rækkerne fra tabellen til venstre, selvom der ikke er fundet nogen matchende rækker i tabellen til højre. Hvor der ikke er fundet nogen match i tabellen til højre, returneres NULL.
SELECT A.`title` , B.`first_name` , B.`last_name` FROM `movies` AS A LEFT JOIN `members` AS B ON B.`movie_id` = A.`id`
Udførelse af ovenstående script i MySQL workbench giver. Du kan se, at i det returnerede resultat, som er angivet nedenfor, har medlemsnavnsfelterne NULL-værdier for film, der ikke er lejet. Det betyder, at der ikke blev fundet noget matchende medlem i medlemstabellen for den pågældende film.
| title | first_name | last_name |
|---|---|---|
| ASSASSIN'S CREED: EMBERS | Adam | Smith |
| Real Steel(2012) | Ravi | Kumar |
| Safe (2012) | Susan | Davidson |
| Deadline(2009) | Jenny | Adrianna |
| Marley and me | Lee | Pong |
| Alvin and the Chipmunks | NULL | NULL |
| The Adventures of Tin Tin | NULL | NULL |
| Safe House(2012) | NULL | NULL |
| GIA | NULL | NULL |
| The Dirty Picture | NULL | NULL |
HØJRE JOIN
RIGHT JOIN er åbenbart det modsatte af LEFT JOIN. RIGHT JOIN returnerer alle kolonnerne fra tabellen til højre, selvom der ikke er fundet nogen matchende rækker i tabellen til venstre. Hvor der ikke er fundet nogen match i tabellen til venstre, returneres NULL.
Lad os i vores eksempel antage, at du skal have navne på medlemmer og film lejet af dem. Nu har vi et nyt medlem, som endnu ikke har lejet nogen film
SELECT A.`first_name` , A.`last_name`, B.`title` FROM `members` AS A RIGHT JOIN `movies` AS B ON B.`id` = A.`movie_id`
Udførelse af ovenstående script i MySQL workbench giver følgende resultater.
| first_name | last_name | title |
|---|---|---|
| Adam | Smith | ASSASSIN'S CREED: EMBERS |
| Ravi | Kumar | Real Steel(2012) |
| Susan | Davidson | Safe (2012) |
| Jenny | Adrianna | Deadline(2009) |
| Lee | Pong | Marley and me |
| NULL | NULL | Alvin and the Chipmunks |
| NULL | NULL | The Adventures of Tin Tin |
| NULL | NULL | Safe House(2012) |
| NULL | NULL | GIA |
| NULL | NULL | The Dirty Picture |
"ON" og "USING" klausuler
Alle forespørgsler har indtil videre matchet rækker med en ON-klausul. MySQL tilbyder et kortere alternativ, når de matchende kolonner deler samme navn.
I ovenstående JOIN-forespørgselseksempler har vi brugt ON-sætning til at matche posterne mellem tabeller.
USING-klausulen kan også bruges til samme formål. Forskellen med BRUG er det skal have identiske navne for matchede kolonner i begge tabeller.
I "film"-tabellen har vi indtil videre brugt dens primære nøgle med navnet "id". Vi henviste til det samme i "members"-tabellen med navnet "movie_id".
Lad os omdøbe "movies"-tabeller til "id"-feltet for at få navnet "movie_id". Vi gør dette for at have identiske matchede feltnavne.
ALTER TABLE `movies` CHANGE `id` `movie_id` INT( 11 ) NOT NULL AUTO_INCREMENT;
Lad os derefter bruge USING med ovenstående LEFT JOIN eksempel.
SELECT A.`title` , B.`first_name` , B.`last_name` FROM `movies` AS A LEFT JOIN `members` AS B USING ( `movie_id` )
Bortset fra at bruge ON og BRUG med JOINs du kan bruge mange andre MySQL klausuler som GROUP BY, HVOR og endda funktioner som SUM, AVGOsv




