Microsoft Power BI • Data Preparation with Power Query

Merging Queries — Merge queries (join tables) and choose join types (intro-to-standard)

Master relational joins in Power Query to combine disparate tables into unified, analysis-ready datasets.

Microsoft Power BI emblem with a dashboard, stacked chart, and database.
Inside this lesson 10 sections 5 questions 8 figures

SECTION 1

Historical Context & Motivation

The need to combine data from multiple tables is as old as the relational model itself. When Edgar F. Codd published his seminal paper in 1970, he formalized the concept of relational algebra, which included join operations as first-class primitives for combining tuples across relations based on shared attributes. This mathematical foundation underpins every modern database system and, by extension, every data transformation tool that operates on tabular data. Power Query, the data preparation engine embedded in Microsoft Power BI, Excel, and Azure Data Factory, inherits this lineage directly — its Merge Queries feature is essentially a GUI-driven implementation of the classic relational join.

Before self-service BI tools existed, analysts relied on database administrators to write SQL JOIN statements or used complex VLOOKUP chains in spreadsheets — both approaches were error-prone and inaccessible to non-technical users. Microsoft introduced Power Query (initially as a free Excel add-in called "Data Explorer") precisely to democratize the extract-transform-load (ETL) pipeline. The merge operation became one of its most powerful features, enabling users to perform inner, outer, cross, and anti joins without writing a single line of SQL or M code.

1970 • Codd's Relational Model

Edgar F. Codd publishes "A Relational Model of Data for Large Shared Data Banks," formalizing join operations in relational algebra and setting the theoretical groundwork for all future data combination techniques.

1986 • SQL Standard Adopted

ANSI adopts SQL as the standard language for relational databases. The JOIN clause (INNER, LEFT, RIGHT, FULL OUTER) becomes the primary mechanism for combining tables, establishing terminology still used in Power Query today.

2013 • Power Query for Excel

Microsoft releases Power Query as an Excel add-in (codenamed "Data Explorer"), bringing GUI-based merge and append operations to business analysts without requiring SQL expertise.

2015 • Power BI Desktop Launches

Power BI Desktop ships with Power Query Editor integrated natively. Merge Queries becomes a core feature for data modeling, supporting six distinct join types with a visual matching interface.

2020+ • Dataflows & Enhanced AI

Power Query expands into cloud-based Dataflows and gains fuzzy matching capabilities for merge operations, enabling approximate joins on non-identical keys — a significant evolution beyond classical exact-match joins.

The central question that merge queries address is deceptively simple: how do you combine rows from two tables that share a logical relationship? Whether you are linking a sales fact table to a product dimension, associating customer IDs across CRM and billing systems, or reconciling inventory records from two warehouses, the merge operation provides a declarative, reproducible way to perform that combination. Understanding which join type to select — and why — is what separates a correct, complete result from one riddled with missing rows or unintended duplicates.

SECTION 2

Core Principles & Definitions

Before executing a merge in Power Query, you must internalize a handful of foundational concepts that map directly to relational database theory. A merge in Power Query is the equivalent of a SQL JOIN: it produces a new table whose rows are determined by matching values in one or more key columns shared between a primary query (left table) and a secondary query (right table). The result initially appears as a nested table column, which you then expand to surface the desired fields. This two-phase workflow — match, then expand — is a distinctive Power Query design pattern that gives you fine-grained control over which columns enter your data model.

1

Key Column(s)

The column(s) used to match rows between the two tables. Analogous to a primary key / foreign key relationship in a relational database. You may select multiple key columns for composite joins.
2

Join Type

Determines which rows are retained in the output. Power Query supports six types: Left Outer, Right Outer, Full Outer, Inner, Left Anti, and Right Anti. Each corresponds to a well-defined set-theoretic operation on the matched key values.
3

Cardinality Awareness

A one-to-many key relationship produces row duplication on the 'one' side. Understanding whether your join keys form a 1:1, 1:N, or M:N relationship is essential to predicting output row count.
4

Expand vs. Aggregate

After merging, the nested table column can be expanded (surfacing individual columns) or aggregated (computing counts, sums, etc.). This decision shapes the granularity of the resulting table and directly affects downstream measures.
5

Merge vs. Append

Merge combines columns horizontally (like a JOIN), while Append stacks rows vertically (like a UNION). Confusing the two is a common beginner mistake that yields entirely wrong results.
✦

KEY TAKEAWAY

Think of merging queries like performing a database-style lookup in a spreadsheet — but instead of writing fragile VLOOKUP formulas, you are declaring a relationship between two tables and letting the engine figure out the row matching. If Append is gluing pages together end-to-end (vertical concatenation), then Merge is stapling two pages side-by-side based on matching row identifiers (horizontal join). Choosing the right join type is equivalent to deciding which unmatched rows you want to keep versus discard.

SECTION 3

Visual Explanation — The Six Join Types

The following Venn-style diagram illustrates the six join types available in Power Query's Merge dialog. Each join type is defined by which region of the Venn diagram it retains: the intersection (matched rows), the left-only region (rows in the primary query with no match), the right-only region (rows in the secondary query with no match), or some combination thereof. Understanding this visual vocabulary is essential because Power Query's merge dialog presents these options in a drop-down, and selecting the wrong one is the single most common source of incorrect results.

Power Query Join Types — Venn Diagram ReferenceLeft TableRight TableMatchedRowsLeft-onlyRight-onlyInner JoinLeft OuterRight OuterFull OuterLeft AntiRight Anti∩ onlyAll left + ∩All right + ∩All left + rightLeft − ∩Right − ∩
The six join types in Power Query mapped to Venn regions. Inner keeps only the intersection. Left/Right Outer keep all rows from one side plus matches. Full Outer keeps everything. Anti joins keep only the non-matching rows from one side.

In the diagram above, the left circle represents rows from the primary (left) query and the right circle represents the secondary (right) query. The overlapping region contains rows where the key column values match across both tables. When you open Power Query's Merge dialog, you select one option from a drop-down that directly corresponds to these six regions. The default selection is Left Outer (all from first, matching from second), which is the safest general-purpose choice because it guarantees you never lose rows from your primary table while still enriching them with data from the secondary table wherever a match exists.

SECTION 4

How Merge Queries Works Under the Hood

While Power Query provides a graphical interface for merging, every merge operation generates an expression in M language (also known as Power Query Formula Language). Understanding the generated code deepens your ability to debug merges, optimize performance, and handle edge cases. The core function is Table.NestedJoin, which takes the left table, left key column(s), right table, right key column(s), a name for the new nested column, and a JoinKind enumeration value.

M LANGUAGE MERGE SYNTAX

Table.NestedJoin(LeftTable,"KeyCol",RightTable,"KeyCol","NewCol",JoinKind.LeftOuter)Table.NestedJoin(LeftTable, {"KeyCol"}, RightTable, {"KeyCol"}, "NewCol", JoinKind.LeftOuter)

Parameters: LeftTable = primary query, {"KeyCol"} = list of key columns (supports composite keys), RightTable = secondary query, "NewCol" = name for the resulting nested table column, JoinKind.* = one of LeftOuter, RightOuter, FullOuter, Inner, LeftAnti, RightAnti.

After the merge step, the result table contains all columns from the left table plus a single new column of type Table. Each cell in this column is itself a table containing the matched row(s) from the right table. To bring those columns into the flat result, you use Table.ExpandTableColumn, specifying which columns to surface. This two-step process — join then expand — is deliberate: it prevents accidental inclusion of every column from the right table, which could bloat your data model.

EXPAND STEP

Table.ExpandTableColumn(MergedTable,"NewCol","Col1","Col2","Right.Col1","Right.Col2")Table.ExpandTableColumn(MergedTable, "NewCol", {"Col1", "Col2"}, {"Right.Col1", "Right.Col2"})

The third parameter lists which columns from the nested table to expand; the fourth provides renamed output column names to avoid ambiguity with left-table columns.

Cardinality and Row Count Impact

A critical consideration when merging is the relationship cardinality between the key columns. If the key in the right table is unique (1:1 or 1:N from left to right), the output row count will not exceed the left table's row count. However, if the right table's key contains duplicates relative to the left (creating an M:N scenario), the output will contain a Cartesian product of matched rows — potentially multiplying the row count dramatically. In formal terms, if a left-table key value k appears m times and the same key value appears n times in the right table, the merge produces m × n rows for that key value. Failing to account for this is a frequent source of inflated aggregates in downstream reports.

CARDINALITY FORMULA

Outputrowsforkeyk=m(k)×n(k)Output rows for key k = m(k) × n(k)

Where m(k) is the count of rows with key value k in the left table, and n(k) is the count in the right table. Total output = Σ m(k) × n(k) for all matched k, plus unmatched rows depending on join type.

SECTION 5

Detailed Breakdown of Each Join Type

Each of the six join types serves a distinct analytical purpose. Selecting the wrong type is a semantic error — Power Query will not throw an exception, but your results will be silently incorrect. The table below provides a comprehensive reference, mapping each Power Query join kind to its SQL equivalent, its set-theoretic definition, and a canonical use case.

Join TypeSQL EquivalentRows RetainedTypical Use Case
Left OuterLEFT JOINAll left rows; matching right rows (nulls where no match)Enrich a fact table with dimension attributes; keep all transactions even if some products are unmatched
Right OuterRIGHT JOINAll right rows; matching left rows (nulls where no match)Ensure every item in the secondary table appears; useful when the right table is the authoritative list
Full OuterFULL OUTER JOINAll rows from both tables; nulls on whichever side lacks a matchData reconciliation — identify mismatches between two systems (e.g., CRM vs. billing)
InnerINNER JOINOnly rows with matching keys in both tablesStrict intersection — only show orders that have a known customer in the customer table
Left AntiLEFT JOIN WHERE right IS NULLLeft rows that have no match in the right tableFind orphan records — orders referencing products not in the product master
Right AntiRIGHT JOIN WHERE left IS NULLRight rows that have no match in the left tableFind unused dimension entries — products that have never been ordered

Complete reference of Power Query join types with SQL equivalents and use cases

Merge Queries — Data Flow DiagramOrders (Left)OrderID CustID Amt 101 C01 $50 102 C02 $30 103 C03 $70 104 C05 $20Customers (Right)CustID Name C01 Alice C02 Bob C04 DianaKey: CustIDMERGE(Left Outer)Result (Left Outer)OrderID CustID Amt Name 101 C01 $50 Alice 102 C02 $30 Bob 103 C03 $70 null 104 C05 $20 nullC03, C05 have no match → nullC04 (Diana) dropped — not in leftIf Inner Join instead:OrderID CustID Amt Name 101 C01 $50 Alice 102 C02 $30 BobOnly 2 rows — unmatched rows dropped
Data flow from two source tables through a merge operation. The highlighted CustID columns are the join keys. The left outer result retains all four orders; the inner join alternative would discard orders 103 and 104 because C03 and C05 have no match in the Customers table.
💡

Anti Joins — The Underused Power Tool

Many analysts overlook anti joins, but they are invaluable for data quality checks. A Left Anti join on Orders → Customers reveals orphan orders (referencing non-existent customers), while a Right Anti join reveals inactive customers (present in the dimension but never in the fact table). In SQL, achieving this requires a LEFT JOIN with a WHERE ... IS NULL filter — Power Query makes it a single dropdown selection.

SECTION 6

Worked Example — Merging Sales and Products

Suppose you have loaded two queries into Power Query Editor: a Sales table containing transaction records and a Products table containing product metadata. You want to enrich each sales record with the product's category and unit price from the Products table, while retaining all sales rows even if a product lookup fails. This calls for a Left Outer join on the shared ProductID column.

Merging Sales with Products (Left Outer Join)

  1. 1

    Step 1 — Open Merge Dialog

    In Power Query Editor, select the Sales query. Navigate to Home → Merge Queries (or Merge Queries as New if you want a separate output query). The merge dialog opens with Sales pre-selected as the primary (top) table.
  2. 2

    Step 2 — Select the Secondary Table

    From the second drop-down, choose the Products query. Both table previews are now visible in the dialog.
  3. 3

    Step 3 — Specify the Key Column(s)

    Click the ProductID column header in the Sales preview, then click the ProductID column header in the Products preview. A green checkmark confirms the key pairing. The status bar at the bottom shows how many rows from the first table matched rows in the second table (e.g., "The selection matches 847 of 900 rows from the first table").
    847 of 900 rows matched — 53 Sales rows have a ProductID not found in the Products table.
  4. 4

    Step 4 — Choose the Join Type

    Open the Join Kind drop-down and select Left Outer (all from first, matching from second). This ensures all 900 sales rows remain in the output, with null values for Product columns where no match exists. Click OK.
  5. 5

    Step 5 — Expand the Nested Column

    A new column named Products appears at the right edge of the Sales table. Each cell contains a nested Table value. Click the expand icon (↔) in the column header. Uncheck ProductID (already present in Sales) and keep Category and UnitPrice. Uncheck "Use original column name as prefix" if you prefer clean column names. Click OK.
    Final result: 900-row table with columns OrderID, ProductID, Qty, Category, UnitPrice. The 53 unmatched rows show null for Category and UnitPrice.
  6. 6

    Step 6 — Verify with M Code

    Open the Advanced Editor to inspect the generated M. The merge step should read: Table.NestedJoin(Sales, {"ProductID"}, Products, {"ProductID"}, "Products", JoinKind.LeftOuter). The expand step reads: Table.ExpandTableColumn(Source, "Products", {"Category", "UnitPrice"}). Confirming these steps against expectations is a best practice before closing the editor.

SECTION 7

Strengths, Limitations & Comparison with Alternatives

AspectPower Query MergeDAX RELATED / LOOKUPVALUESQL JOIN (DirectQuery)
Execution timeAt refresh time — result is materialized in the data modelAt query time — computed on every visual interactionAt query time — executed by the source database engine
Supports anti joinsYes — native Left Anti and Right Anti optionsRequires workaround with EXCEPT or ISBLANK filtersYes — via WHERE ... IS NULL pattern
DenormalizationFlattens into a single table — increases model size but simplifies measuresPreserves star schema — smaller model but more complex DAXDepends on view/query design
Fuzzy matchingSupported via Fuzzy Merge option with similarity thresholdNot natively supportedRequires custom functions (e.g., SOUNDEX, Levenshtein)
Best forETL-phase enrichment, denormalization, data quality auditsDynamic lookups that depend on filter contextLarge datasets where you want to push computation to the server

Comparison of data combination methods in the Power BI ecosystem

⚖️

WHEN TO MERGE VS. WHEN TO MODEL

Think of the trade-off like compiling versus interpreting code. A Power Query merge is like ahead-of-time compilation — the join is resolved once at data refresh and the flat result is stored in memory. A DAX relationship-based lookup is like just-in-time interpretation — evaluated dynamically whenever a visual queries the model. Use merge when you want to reduce downstream DAX complexity or when you need anti-join semantics. Rely on model relationships when the star schema is already well-designed and you want to minimize data redundancy.

SECTION 8

Connection to Advanced Theory — Fuzzy Merge & Query Folding

The standard merge operation in Power Query performs exact-match joins, but real-world data is messy. Power Query offers Fuzzy Merge, which uses a similarity algorithm (based on Jaccard distance over character n-grams) to match keys that are close but not identical — for example, joining "Microsoft Corp" to "Microsoft Corporation." You configure a similarity threshold between 0 and 1, where 1 requires an exact match. This feature bridges the gap between Power Query's GUI-driven ETL and the kind of probabilistic record linkage typically handled by specialized tools or custom Python scripts.

FeatureStandard MergeFuzzy Merge
Matching logicExact equality on key valuesSimilarity score ≥ threshold (Jaccard on n-grams)
PerformanceHash-based; fast even on large tablesO(m × n) comparisons; slow on large tables without transformation table
Query foldingCan fold to SQL JOIN on supported sourcesNever folds — always processed by the mashup engine locally
Use caseClean, normalized data with consistent keysDirty data with typos, abbreviations, or inconsistent formatting

Standard merge vs. fuzzy merge capabilities

Another advanced consideration is query folding. When both tables originate from the same SQL-based source, Power Query can translate the merge step into a native SQL JOIN statement and push the computation to the database engine. This dramatically improves performance because the data never leaves the server until after the join. You can verify whether folding occurred by right-clicking the merge step in the Applied Steps pane and selecting View Native Query. If the option is grayed out, folding has broken — often because a prior step (like a custom M function or a manual table construction) is not foldable. Designing your Power Query pipeline with folding in mind is a key optimization technique for enterprise-scale datasets.

ℹ

Looking Ahead

As you progress to building production-grade Power BI solutions, you will encounter scenarios requiring incremental refresh combined with merge queries, composite models where some tables are imported (merged at refresh) and others are DirectQuery (joined at query time), and Dataflows that centralize merge logic in the cloud for reuse across multiple reports. Mastering the fundamentals here provides the essential groundwork for all of these advanced patterns.

SECTION 9

Practice Problems

Question 1: CONCEPTUAL

Explain the difference between a Left Outer join and a Left Anti join in Power Query. For each, describe which rows from the left and right tables appear in the output.
Show answer
A Left Outer join retains all rows from the left (primary) table. For rows where the key matches a row in the right table, the right table's columns are populated; for unmatched rows, those columns contain null. In contrast, a Left Anti join returns only the left-table rows that do not have a matching key in the right table — and it includes no columns from the right table at all. Essentially, the Left Outer join is the union of the matched set and the left-only set, while the Left Anti join isolates exclusively the left-only set. Anti joins are particularly useful for data quality audits — for instance, finding sales records that reference invalid product IDs.

Question 2: BASIC CALCULATION

Table A has 500 rows with unique values in column ID. Table B has 300 rows with unique values in column ID. Of these, 200 ID values are common to both tables. How many rows will result from each of the six join types?
Show answer
Since both tables have unique key values, there is no M:N duplication. Inner join: 200 rows (only matches). Left Outer: 500 rows (all of A; 200 matched, 300 with nulls from B). Right Outer: 300 rows (all of B; 200 matched, 100 with nulls from A). Full Outer: 600 rows (200 matched + 300 left-only + 100 right-only). Left Anti: 300 rows (A rows with no match in B). Right Anti: 100 rows (B rows with no match in A). The general formula for Full Outer with unique keys is |A| + |B| − |A ∩ B| = 500 + 300 − 200 = 600.

Question 3: INTERMEDIATE

You merge an Orders table (10,000 rows) with a Products table (500 rows, unique ProductID) using an Inner join on ProductID. After the merge, you notice the result has 9,750 rows. What does this tell you about your data, and what would happen if you switched to a Left Outer join?
Show answer
Since the Products table has unique ProductIDs, the inner join cannot produce more rows than the left table — it can only reduce them. The result of 9,750 rows (vs. 10,000) means that 250 orders reference ProductIDs that do not exist in the Products table; these unmatched rows were discarded by the inner join. If you switch to a Left Outer join, all 10,000 order rows would be retained, with 250 of them having null values in the expanded Product columns. This is a data quality signal: those 250 orders either contain typos in ProductID, or the Products table is missing entries. You could use a Left Anti join to isolate exactly those 250 orphan records for investigation.

Question 4: APPLIED

A university registrar maintains two tables: Enrollments (StudentID, CourseID, Semester) with 50,000 rows and Students (StudentID, Name, Major) with 8,000 rows. Some students graduated and were removed from the Students table but still have enrollment records. The registrar wants to: (a) produce a report of all enrollments with student names, and (b) identify enrollments belonging to deleted students. Describe the merge operations and join types needed for each task.
Show answer
For task (a), use a Left Outer join with Enrollments as the left table and Students as the right table, joined on StudentID. This preserves all 50,000 enrollment records. Where a student still exists, the Name and Major columns will be populated; for deleted students, those columns will show null. For task (b), use a Left Anti join with the same table configuration: Enrollments (left) merged with Students (right) on StudentID. The result will contain only the enrollment rows whose StudentID is not present in the Students table — these are the 'orphan' records belonging to deleted students. Alternatively, after the Left Outer merge from task (a), you could filter where Name is null to achieve the same result, but the anti join is more semantically direct and avoids loading unnecessary columns.

Question 5: CRITICAL THINKING

Consider a scenario where you merge a Sales table with a CustomerSegment table on CustomerID, but the CustomerSegment table is a slowly changing dimension (SCD Type 2) where each customer can have multiple rows representing different time periods (with EffectiveDate and ExpiryDate columns). A standard merge on CustomerID alone produces a Cartesian product. Propose a strategy using Power Query to achieve a correct point-in-time join that associates each sale with the customer segment that was active on the sale date.
Show answer
A standard merge on CustomerID alone will indeed produce M:N row multiplication because each customer has multiple segment rows. Power Query's merge dialog does not natively support range-based or inequality joins (e.g., SaleDate BETWEEN EffectiveDate AND ExpiryDate). The recommended strategy involves multiple steps. First, merge Sales and CustomerSegment on CustomerID using a Left Outer join, accepting the intentional row multiplication. Second, after expanding the EffectiveDate and ExpiryDate columns, add a custom filter step in M that retains only rows where the SaleDate falls within [EffectiveDate, ExpiryDate]: each row satisfying SaleDate >= EffectiveDate and (SaleDate <= ExpiryDate or ExpiryDate = null). This effectively simulates a range join. However, be aware this approach is computationally expensive and breaks query folding. For large datasets, it is more efficient to push this logic to the source database using a native SQL query step or a database view with the temporal join logic, allowing the database optimizer to handle it efficiently. This is a common pattern where understanding the limitations of GUI-driven ETL motivates architectural decisions about where join logic should reside.

SUMMARY

Summary

Summary

Power Query's Merge Queries feature implements relational join operations through a two-phase workflow: first, match rows between a primary (left) table and a secondary (right) table using one or more key columns; second, expand the nested result column to surface the desired fields. Power Query supports six join types: Inner (intersection only), Left Outer (all left + matches), Right Outer (all right + matches), Full Outer (all from both), Left Anti (unmatched left rows), and Right Anti (unmatched right rows).

Choosing the correct join type is a semantic decision that directly affects result correctness. Always verify the cardinality of your key columns — M:N relationships cause row multiplication via Cartesian products. Under the hood, each merge generates Table.NestedJoin in M code, and the expand step generates Table.ExpandTableColumn. For performance-critical pipelines, verify that query folding is maintained by checking whether the native query option is available. Advanced scenarios include Fuzzy Merge for approximate matching and architectural patterns for handling slowly changing dimensions.

Varsity Tutors • Microsoft Power BI • Merging Queries — Merge queries (join tables) and choose join types (intro-to-standard)