12/07/2014
At kombinere data fra flere forskellige kilder er en fundamental del af dataforberedelse og analyse. Uanset om du arbejder med salgsdata, kundeoplysninger eller lagerstatus, er evnen til at flette tabeller korrekt afgørende for at skabe meningsfulde rapporter og indsigter. I Power Query, Microsofts kraftfulde værktøj til datatransformation, er 'joins' eller sammenføjninger den centrale mekanisme til at opnå dette. Funktionen Table.Join giver brugerne mulighed for nemt at udføre forskellige typer af sammenføjninger. Denne artikel vil fungere som din dybdegående guide til at mestre Inner, Outer og Anti joins ved hjælp af praktiske eksempler i Power Query M-sproget.

Hvad er Table.Join i Power Query?
Table.Join er en kernefunktion i Power Query M-sproget, der giver dig mulighed for at kombinere rækkerne fra to tabeller baseret på matchende værdier i en eller flere specificerede kolonner. Denne operation er meget lig de velkendte JOIN-operationer i SQL og er uundværlig for enhver, der arbejder seriøst med dataanalyse og rapportering. Ved at forstå de forskellige join-typer kan du præcist styre, hvilke data der inkluderes eller ekskluderes i dit endelige datasæt.
Power Query understøtter flere join-typer gennem parameteren JoinKind. Her er en oversigt over de mest almindelige:
- Inner Join: Returnerer kun de rækker, der har et match i begge tabeller.
- Left Outer Join: Returnerer alle rækker fra den venstre (første) tabel og de matchende rækker fra den højre (anden) tabel.
- Right Outer Join: Returnerer alle rækker fra den højre tabel og de matchende rækker fra den venstre tabel.
- Full Outer Join: Returnerer alle rækker fra begge tabeller. Hvor der er et match, kombineres rækkerne.
- Left Anti Join: Returnerer kun de rækker fra den venstre tabel, som IKKE har et match i den højre tabel.
- Right Anti Join: Returnerer kun de rækker fra den højre tabel, som IKKE har et match i den venstre tabel.
Syntaks for Table.Join
Den grundlæggende syntaks for funktionen ser således ud:
Table.Join(table1 as table, key1 as any, table2 as table, key2 as any, joinKind as nullable text, optional joinAlgorithm as nullable text, optional keyEqualityComparers as nullable list) as table
Lad os bryde de vigtigste parametre ned:
table1: Den venstre tabel i sammenføjningen.key1: Kolonnen (eller kolonnerne) fratable1, der skal bruges til at matche.table2: Den højre tabel i sammenføjningen.key2: Kolonnen (eller kolonnerne) fratable2, der skal bruges til at matche.joinKind: Typen af join, der skal udføres (f.eks.JoinKind.Inner).
Praktiske Eksempler: Data og Opsætning
For at illustrere de forskellige join-typer vil vi bruge to simple, men relaterede datasæt: Kundedata og Ordredata. Forestil dig, at vi har indlæst disse data fra Excel til Power Query.
Kundedata (Customer Data)
Denne tabel indeholder grundlæggende oplysninger om vores kunder.
| Customer ID | Customer Name | Country |
|---|---|---|
| 101 | John Smith | USA |
| 102 | Jane Doe | Canada |
| 103 | Peter Jones | UK |
| 104 | Anna Bell | USA |
Ordredata (Order Data)
Denne tabel indeholder oplysninger om de ordrer, der er blevet placeret.
| Order ID | Order Date | Product | CustomerID |
|---|---|---|---|
| 5001 | 2023-01-15 | Laptop | 101 |
| 5002 | 2023-02-20 | Mouse | 102 |
| 5003 | 2023-03-05 | Keyboard | 101 |
| 5004 | 2023-04-10 | Monitor | 105 |
Bemærk, at kunde 103 og 104 ikke har nogen ordrer, og ordre 5004 er tilknyttet kunde 105, som ikke findes i vores kundetabel. Disse uoverensstemmelser er perfekte til at demonstrere styrken ved de forskellige join-typer.
Dyk ned i de forskellige Join-typer
1. Inner Join: Kombination af matchende rækker
Et Inner Join returnerer kun de rækker, hvor nøglekolonnen (i vores tilfælde Customer ID) findes i begge tabeller. Det er den mest restriktive join-type.
Power Query M-kode:
let
InnerJoinTable = Table.Join(#"Customer Data", {"Customer ID"}, #"Order Data", {"CustomerID"}, JoinKind.Inner)
in
InnerJoinTable
Resultat:
- Kun kunder, der har afgivet en ordre, vil blive vist (John Smith og Jane Doe).
- Kunderne 103 (Peter Jones) og 104 (Anna Bell) udelades, da de ikke har nogen ordrer.
- Ordre 5004 udelades, fordi dens CustomerID (105) ikke findes i kundetabellen.
- John Smith (101) optræder to gange, fordi han har to ordrer.
Bedst anvendt når: Du kun ønsker at se komplette poster, hvor der findes relateret information i begge tabeller, f.eks. en liste over kunder OG deres specifikke ordrer.
2. Left Outer Join: Bevar alle rækker fra venstre tabel
Et Left Outer Join returnerer alle rækker fra den venstre tabel (table1), uanset om der er et match i den højre tabel. Hvis der er et match, tilføjes data fra den højre tabel. Hvis ikke, vil kolonnerne fra den højre tabel indeholde null-værdier.
Power Query M-kode:
let
LeftOuterTable = Table.Join(#"Customer Data", {"Customer ID"}, #"Order Data", {"CustomerID"}, JoinKind.LeftOuter)
in
LeftOuterTable
Resultat:
- Alle kunder fra kundetabellen er med i resultatet.
- Kunder uden ordrer (103 og 104) vises, men har
null-værdier i ordrekolonnerne (Order ID, Order Date osv.). - Ordre 5004 er stadig udeladt, da dens CustomerID ikke matcher nogen kunder i den venstre (kunde) tabel.
Bedst anvendt når: Du vil have en komplet liste fra din primære tabel (f.eks. alle kunder) og berige den med information fra en sekundær tabel, hvis den findes (f.eks. deres ordrer).
3. Right Outer Join: Bevar alle rækker fra højre tabel
Et Right Outer Join er det omvendte af et Left Outer Join. Det returnerer alle rækker fra den højre tabel (table2) og kun de matchende rækker fra den venstre tabel.
Power Query M-kode:
let
RightOuterTable = Table.Join(#"Customer Data", {"Customer ID"}, #"Order Data", {"CustomerID"}, JoinKind.RightOuter)
in
RightOuterTable
Resultat:
- Alle ordrer fra ordretabellen er med i resultatet.
- Ordre 5004, som ikke har en matchende kunde, vises med
null-værdier i kundekolonnerne (Customer Name, Country). - Kunder uden ordrer (103 og 104) udelades helt.
Bedst anvendt når: Du vil have en komplet liste fra din sekundære tabel (f.eks. alle ordrer) og se, hvilke der har tilknyttet information fra den primære tabel.
4. Full Outer Join: Bevar alle rækker fra begge tabeller
Et Full Outer Join er den mest inkluderende join-type. Den returnerer alle rækker fra begge tabeller. Hvor der er et match, kombineres rækkerne. Hvor der ikke er et match, indsættes null-værdier.
Power Query M-kode:
let
FullOuterTable = Table.Join(#"Customer Data", {"Customer ID"}, #"Order Data", {"CustomerID"}, JoinKind.FullOuter)
in
FullOuterTable
Resultat:
- Alle kunder og alle ordrer er med i resultatet.
- Kunder uden ordrer (103, 104) har
nulli ordrekolonnerne. - Ordrer uden matchende kunder (5004) har
nulli kundekolonnerne.
Bedst anvendt når: Du har brug for et komplet overblik over alle data fra begge tabeller og vil identificere uoverensstemmelser eller manglende relationer i begge retninger.
5. Anti Joins: Find rækker uden match
Anti Joins er fantastiske til fejlfinding og dataoprydning. De bruges til at finde rækker i én tabel, der *ikke* har et match i den anden.
Left Anti Join: Rækker kun i venstre tabel
Returnerer rækker fra den venstre tabel, som ikke har et match i den højre tabel. Resultatet indeholder kun kolonner fra den venstre tabel.
Power Query M-kode:
let
LeftAntiTable = Table.Join(#"Customer Data", {"Customer ID"}, #"Order Data", {"CustomerID"}, JoinKind.LeftAnti)
in
LeftAntiTable
Resultat: Viser kun kunderne 103 (Peter Jones) og 104 (Anna Bell), da de er de eneste kunder uden ordrer.
Bedst anvendt når: Du vil finde poster i din primære tabel, der mangler en tilsvarende post i den sekundære tabel (f.eks. finde kunder, der aldrig har købt noget).
Right Anti Join: Rækker kun i højre tabel
Returnerer rækker fra den højre tabel, som ikke har et match i den venstre tabel. Resultatet indeholder kun kolonner fra den højre tabel.
Power Query M-kode:
let
RightAntiTable = Table.Join(#"Customer Data", {"Customer ID"}, #"Order Data", {"CustomerID"}, JoinKind.RightAnti)
in
RightAntiTable
Resultat: Viser kun ordre 5004, da den tilhører en kunde (105), der ikke findes i kundetabellen.
Bedst anvendt når: Du vil finde poster i din sekundære tabel, der mangler en tilsvarende post i den primære tabel (f.eks. ordrer med ugyldige kunde-ID'er).
En af de mest almindelige fejl, man støder på med Table.Join, er en fejl om duplikerede kolonnenavne. Dette sker ofte med outer joins, fordi Power Query forsøger at inkludere nøglekolonnen fra begge tabeller, og de har typisk samme navn.
Fejlen kan se sådan ud: Expression.Error: A join operation cannot result in a table with duplicate column names ["Customer ID"]
Her er tre effektive metoder til at løse dette problem:
Løsning 1: Omdøb kolonner før sammenføjning
Den simpleste løsning er at omdøbe nøglekolonnen i en af tabellerne, før du udfører join-operationen.
let
// Omdøb CustomerID i Ordredata-tabellen
OrderDataRenamed = Table.RenameColumns(OrderData, {{"CustomerID", "Order_CustomerID"}}),
JoinResult = Table.Join(CustomerData, "Customer ID", OrderDataRenamed, "Order_CustomerID", JoinKind.LeftOuter)
in
JoinResult
Løsning 2: Brug Table.NestedJoin
En mere moderne og fleksibel tilgang er at bruge Table.NestedJoin. Denne funktion skaber en ny kolonne, der indeholder en nestet tabel med de matchende rækker fra den anden tabel. Derefter kan du udvide denne kolonne og vælge præcis, hvilke felter du vil inkludere, og hvordan de skal navngives.
let
JoinedTable = Table.NestedJoin(#"Customer Data", {"Customer ID"}, #"Order Data", {"CustomerID"}, "Order Details", JoinKind.LeftOuter),
ExpandedTable = Table.ExpandTableColumn(JoinedTable, "Order Details", {"Order ID", "Order Date", "Product"})
in
ExpandedTable
Denne metode giver dig fuld kontrol og undgår navnekonflikter elegant.
Løsning 3: Brug Table.PrefixColumns
En anden mulighed er at tilføje et præfiks til alle kolonnenavne i en af tabellerne, før du sammenføjer dem. Dette sikrer, at alle kolonnenavne er unikke.
let
// Tilføj præfikset "Order_" til alle kolonner i Ordredata
OrderDataPrefixed = Table.PrefixColumns(OrderData, "Order_"),
JoinResult = Table.Join(CustomerData, "Customer ID", OrderDataPrefixed, "Order_CustomerID", JoinKind.LeftOuter)
in
JoinResult
Resultatet vil have kolonner som "Customer ID", "Order_CustomerID", "Order_Order ID" osv.
Ofte Stillede Spørgsmål (OSS)
- Hvad er den primære forskel på et Inner Join og et Left Outer Join?
- Et Inner Join returnerer kun rækker, der har et match i BEGGE tabeller. Et Left Outer Join returnerer ALLE rækker fra den venstre tabel, uanset om der er et match i den højre. Det betyder, at et Left Outer Join potentielt kan returnere flere rækker og vil indeholde 'null'-værdier for de rækker, der ikke fandt et match.
- Hvorfor er Anti Joins nyttige?
- Anti Joins er ekstremt nyttige til datakvalitetskontrol. De hjælper dig med hurtigt at identificere 'forældreløse' poster – for eksempel kunder uden ordrer (Left Anti) eller ordrer med ugyldige kunde-ID'er (Right Anti). Dette gør det nemt at rense og validere dine data.
- Kan jeg joine på mere end én kolonne?
- Ja, absolut. I
Table.Join-funktionen kan du angive en liste af kolonnenavne for bådekey1ogkey2. For eksempel:Table.Join(tabel1, {"KolonneA", "KolonneB"}, tabel2, {"KolonneX", "KolonneY"}, JoinKind.Inner). Dette er nyttigt, når en unik relation kræver match på flere felter.
Konklusion
At mestre Table.Join i Power Query M-sproget er en afgørende færdighed, der transformerer din evne til at arbejde med data. Ved at forstå de forskellige formål med Inner, Outer og Anti joins kan du præcist forme, kombinere og rense dine datasæt for at forberede dem til analyse og rapportering. Hver join-type tjener et unikt analytisk formål, fra at finde det komplette overlappende datasæt til at isolere uoverensstemmelser. Nøglen til succes ligger i at forstå dine datarelationer og vælge den korrekte join-type til at besvare dit specifikke forretningsspørgsmål. Med denne viden er du godt rustet til at håndtere selv komplekse datafletningsscenarier og udlede dybere, mere præcise indsigter fra dine data.
Hvis du vil læse andre artikler, der ligner Forstå Joins i Power Query: En Komplet Guide, kan du besøge kategorien Sundhed.
