Table.AddJoinColumn เชื่อมต่อข้อมูลจากสองตารางตามคีย์ที่ตรงกัน โดยเก็บผลลัพธ์ในคอลัมน์ใหม่เป็นตารางแบบ nested แทนการขยายแนวนอน
= Table.AddJoinColumn(table1, key1, table2, key2, newColumnName)
= Table.AddJoinColumn(table1, key1, table2, key2, newColumnName)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| table1 | table | Yes | ตารางหลัก (primary table) ที่ต้องการเพิ่มคอลัมน์ join | |
| key1 | text or list | Yes | ชื่อคอลัมน์ (หรือ list หลายคอลัมน์) ในตารางหลักที่ใช้เป็น key สำหรับ join | |
| table2 | function | Yes | ฟังก์ชันที่ return ตารางที่ต้องการ join กับ (ต้องเขียนเป็น () => TableName) | |
| key2 | text or list | Yes | ชื่อคอลัมน์ (หรือ list หลายคอลัมน์) ในตารางที่ join ที่ต้องการเทียบกับ key1 | |
| newColumnName | text | Yes | ชื่อของคอลัมน์ใหม่ที่จะเก็บผลลัพธ์ join (เป็นตารางแบบ nested) |
Custom Join implementation
let Sales = Table.FromRecords({ [SaleID = 1, Item = "Shirt"], [SaleID = 2, Item = "Hat"], [SaleID = 3, Item = "Shoes"] }), PriceData = Table.FromRecords({ [Sale…let
Sales = Table.FromRecords({
[SaleID = 1, Item = "Shirt"],
[SaleID = 2, Item = "Hat"],
[SaleID = 3, Item = "Shoes"]
}),
PriceData = Table.FromRecords({
[SaleID = 1, Price = 200, Stock = 50],
[SaleID = 2, Price = 150, Stock = 80],
[SaleID = 1, Price = 180, Currency = "USD"]
}),
Result = Table.AddJoinColumn(Sales, "SaleID", () => PriceData, "SaleID", "PriceInfo")
in
Result
ตารางขาย 3 แถว + คอลัมน์ PriceInfo ใหม่ที่มีตารางแบบ nested
let Orders = Source, CustomerInfo = () => Excel.CurrentWorkbook(){[Name="Customers"]}[Content], Result = Table.AddJoinColumn(Orders, "CustomerID", CustomerInfo,…let
Orders = Source,
CustomerInfo = () => Excel.CurrentWorkbook(){[Name="Customers"]}[Content],
Result = Table.AddJoinColumn(Orders, "CustomerID", CustomerInfo, "CustomerID", "Customer")
in
Result
ตาราง Orders ที่มีคอลัมน์ Customer ใหม่เป็นตารางแบบ nested
let Table1 = Table.FromRecords({ [Year = 2024, Month = 1, Sales = 1000], [Year = 2024, Month = 2, Sales = 1500], [Year = 2025, Month = 1, Sales = 2000] }), Tabl…let
Table1 = Table.FromRecords({
[Year = 2024, Month = 1, Sales = 1000],
[Year = 2024, Month = 2, Sales = 1500],
[Year = 2025, Month = 1, Sales = 2000]
}),
Table2 = Table.FromRecords({
[Year = 2024, Month = 1, Target = 1200],
[Year = 2024, Month = 2, Target = 1400],
[Year = 2025, Month = 1, Target = 2200]
}),
Result = Table.AddJoinColumn(Table1, {"Year", "Month"}, () => Table2, {"Year", "Month"}, "TargetInfo")
in
Result
ตาราง Table1 + คอลัมน์ TargetInfo ที่มีตาราง Target details
let Orders = Table.FromRecords({ [OrderID = 1, OrderDate = #date(2024,1,1)], [OrderID = 2, OrderDate = #date(2024,1,2)] }), OrderDetails = Table.FromRecords({ […let
Orders = Table.FromRecords({
[OrderID = 1, OrderDate = #date(2024,1,1)],
[OrderID = 2, OrderDate = #date(2024,1,2)]
}),
OrderDetails = Table.FromRecords({
[OrderID = 1, Product = "Chair", Qty = 2],
[OrderID = 1, Product = "Desk", Qty = 1],
[OrderID = 2, Product = "Lamp", Qty = 3]
}),
Joined = Table.AddJoinColumn(Orders, "OrderID", () => OrderDetails, "OrderID", "Details"),
Expanded = Table.ExpandTableColumn(Joined, "Details", {"Product", "Qty"}, {"Product", "Qty"})
in
Expanded
ตาราง Orders ที่มีคอลัมน์ Product และ Qty ขยายออกมา โดยแถวเพิ่มเติมสำหรับแต่ละ Product
Table.Join จะ flatten ผลลัพธ์ออกมาเป็นแถวแยก (multiplication ของแถว) แต่ Table.AddJoinColumn จะเก็บผลลัพธ์ join เป็นตารางแบบ nested ในคอลัมน์เดียว ซึ่งให้ความยืดหยุ่นมากว่า แล้วค่อย expand บางคอลัมน์หรือทั้งหมดก็ได้
เพราะ Power Query จะประมวลผล function นี้อย่างมีประสิทธิภาพ โดยรอจนกว่าจะประเมินค่า key ใน table1 เสร็จสิ้นก่อน หลังจากนั้นค่อยเรียกใช้ table2 ช่วยหลีกเลี่ยงการโหลดตารางทั้งหมดล่วงหน้า และช่วย performance ได้เยอะ ผมแนะนำให้เสมอเขียน () => TableName
จะได้ตารางว่าง (empty table) ในคอลัมน์ nested ของแถวนั้น เพราะเป็น LeftOuter join มีความหมายว่าแถวจาก table1 ยังอยู่แม้ว่าไม่มี match ใน table2 หากต้องการ inner join (เก็บเฉพาะที่มี match) ต้องใช้ Table.Join แทน
ได้ครับ ใช้ list {“Column1”, “Column2”, “Column3”, …} แทนชื่อคอลัมน์เดี่ยว เวลานี้ Power Query จะต้องมีค่าทั้งหมดตรงกัน (composite key)
ผลก็คือคอลัมน์ nested จะมีหลายแถว สำหรับแต่ละแถวจาก table1 ตัวอย่างเช่น order 1 อัน มี product 3 ชนิด คอลัมน์ nested จะเป็นตาราง 3 แถว ผมแนะนำให้ expand มาดูชัดๆ ว่าข้อมูลตรงกับที่คิดไหม
Table.AddJoinColumn รับตารางหลัก ตารางที่ join กับ และข้อกำหนดว่าจะเชื่อมตามคอลัมน์ไหน ผลลัพธ์จะปรากฏในคอลัมน์ใหม่เป็นตารางแบบซ้อน (nested table) ไม่ flatten แบบแนวนอน เป็น LeftOuter join หมายความว่าแถวทั้งหมดจากตารางหลักคงไว้ เพียงแต่เพิ่มข้อมูล match จากตารางที่ join
ที่เจ๋งคือ Table.AddJoinColumn ช่วยให้เก็บความสัมพันธ์ระหว่างข้อมูล (relationship) ไว้ได้อย่างชัดเจน แถมสามารถเลือกว่าจะ expand (flatten) ออกมากี่คอลัมน์ก็ได้ ต่างจาก Table.Join ที่ flatten ทั้งหมดจึงเสียความยืดหยุ่น สำหรับ performance มันก็ดี เพราะเก็บตารางแยกกันไว้
ส่วนตัวผมใช้ฟังก์ชันนี้เวลาต้องการเก็บข้อมูล detail ไว้ก่อน แล้วค่อย expand เฉพาะคอลัมน์ที่ต้องการหลังจากนั้น มันให้ความยืดหยุ่นมากเวลาต้องแก้ไข logic ของ join ได้ง่ายขึ้น 😎