Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Calling all Data Engineers! Fabric Data Engineer (Exam DP-700) live sessions are back! Starting October 16th. Sign up.

Reply
vonschultz666
Helper I
Helper I

How to mimic SQL "Full Outer Join" in M?

Hi everyone!

I have one challenge I would like to resolve with Power Query, and hopefully, someone will be able to help.

Currently, I have two views on two different MS SQL servers. The first view uses local authentication, while the second view uses AD authentication. The result I would like to achieve is written in SQL as follows:

 

SELECT *
FROM [A]
FULL OUTER JOIN [B] ON A.No_=B.SupplierArticleID AND B.Supplier='Firm XXX'

 

 

 

I want to get the following table:

 B.SupplierArticleIDB.Supplier='Firm XXX'B.No_
Row Result 1.10000Yes10000
Row Result 2.10000Nonull
Row Result 3.10001Nonull
Row Result 4.nullnull10002


I've created the following M Power Query:

 

let
    // Add prefix to column names in B and A
    RenameBColumns = Table.TransformColumnNames(B, each "B." & _),
    RenameAColumns = Table.TransformColumnNames(A, each "A." & _),

    // Filter B table for Supplier = 'Firm XXX'
    FilteredB = Table.SelectRows(RenameBColumns, each [B.Supplier] = "Firm XXX"),

    // Perform left outer join 
    LeftJoin = Table.Join(RenameAColumns, "A.No_", FilteredB, "B.ArticleSupplierID", JoinKind.LeftOuter),
		
    // Perform Left Anti Join on A table to get the rows which are not included in LeftJoin
    LeftAntiJoinA = Table.Join(RenameAColumns, "A.No_", LeftJoin, "A.No_", JoinKind.LeftAnti),

    // Perform Right Anti Join on original B table to get the rows which are not included in LeftJoin
    RightAntiJoinB = Table.Join(LeftJoin, "B.ArticleSupplierID", RenameBARColumns, "B.ArticleSupplierID", JoinKind.RightAnti),

    // Combine all tables to mimic full outer join
    FullOuterJoin = Table.Combine({LeftJoin, LeftAntiJoinA, RightAntiJoinB})
in
    FullOuterJoin

 

 

 

The issue arises because when using the LeftJoin, we can cover Row Result 1. With AntiJoins, we can cover Row Results 3. and 4., but Row Result 2. would not be covered. This means that the table RightAntiJoinB might not contain the SupplierArticleID if there are two rows with the same value. Specifically, one row with Supplier = 'Firm XXX' (which would be included in the LeftJoin), and another row without the Supplier value, causing it to be omitted due to the use of the right anti join.

Any idea how to solve this?

1 ACCEPTED SOLUTION

 

The change in the expected output table has changed the problem as I understood it.

If you're able to add a column into TableA specifying a single supplier, then the most efficient method would be the following:

 

Add a column into TableA that is just = "Firm XXX". Let's call it [A.Supplier].

Perform a Full Outer merge on [B.SupplierArticleID] & [B.Supplier] = [A.No_] & [A.Supplier].

You can do a two-field merge by using Ctrl+click on the fields in the merge dialog. Make sure to Ctrl+click the fields in the same order on each table:BA_Pete_0-1688370890543.png

This gives the following output:BA_Pete_2-1688370976927.png

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




View solution in original post

8 REPLIES 8
slorin
Super User
Super User

Hi,

May be ?

Table.NestedJoin(
TableB, {"B.SupplierArticleID", "B.Supplier"},
Table.AddColumn(TableA, "Firm", each "Firm XXX"), {"A.No_", "Firm"},
"NewColumn",
JoinKind.FullOuter
)

Stéphane

BA_Pete
Super User
Super User

Hi @vonschultz666 ,

 

I may be misunderstanding your requirements, but you can perform a Full Outer merge in Power Query.

Once you get to this point:

let
    // Add prefix to column names in B and A
    RenameBColumns = Table.TransformColumnNames(B, each "B." & _),
    RenameAColumns = Table.TransformColumnNames(A, each "A." & _),

    // Filter B table for Supplier = 'Firm XXX'
    FilteredB = Table.SelectRows(RenameBColumns, each [B.Supplier] = "Firm XXX"),

 

... you can just Full Outer on A.No_ = FilteredB.SupplierArticleID:

BA_Pete_0-1688132837470.png

 

Am I missing something?

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




I think i forgot to mention one importatnt thing, full outer join in M can't have two conditions, therefore full outer join in SQL is a perfect fit for me, but in M not so much!

I would get only a subset of data with your proposal...

Any other ideas perhaps?

 

It can't have two conditions in the way that you need it to i.e. the B.Supplier = 'Firm XXX' condition, but filtering table B on [Supplier] = "Firm XXX" before the merge satisfies this condition ahead of the merge, so you only need to satisfy the A.No_ = FilteredB.SupplierArticleID condition, which PQ can do just fine.

 

I'm obviously missing something here, so can you provide copyable example of both TableA and TableB before the merge that you would expect to become your example output table please?

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




Hi,

ignore the above merged table (i've put something wrong), this is the right one:

Table B:

B.SupplierArticleIDB.Supplier
10000Firm XXX
10000Firm YYY
10001null

 

Table A:

A.No_A.Item
10000Item 01
10002Item 02

 

Result:

B.SupplierArticleIDB.SupplierA.No_A.Item
10000Firm XXX10000Item 01
10000Firm YYYnullnull
10001nullnullnull
nullnull10002Item 02

Any idea @BA_Pete ?

 

The change in the expected output table has changed the problem as I understood it.

If you're able to add a column into TableA specifying a single supplier, then the most efficient method would be the following:

 

Add a column into TableA that is just = "Firm XXX". Let's call it [A.Supplier].

Perform a Full Outer merge on [B.SupplierArticleID] & [B.Supplier] = [A.No_] & [A.Supplier].

You can do a two-field merge by using Ctrl+click on the fields in the merge dialog. Make sure to Ctrl+click the fields in the same order on each table:BA_Pete_0-1688370890543.png

This gives the following output:BA_Pete_2-1688370976927.png

 

Pete



Now accepting Kudos! If my post helped you, why not give it a thumbs-up?

Proud to be a Datanaut!




This works, thanks! 😄

Helpful resources

Announcements
FabCon Global Hackathon Carousel

FabCon Global Hackathon

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes!

October Power BI Update Carousel

Power BI Monthly Update - October 2025

Check out the October 2025 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Kudoed Authors