Table.FuzzyJoin ใช้สำหรับเชื่อม 2 ตารางเข้าด้วยกันโดยใช้คีย์ที่มีความคล้ายคลึงกัน (Fuzzy Matching) แทนที่จะต้องเหมือนกันทุกตัวอักษร สามารถกำหนดระดับความเหมือน (Threshold) และตัวเลือกอื่นๆ ได้
=Table.FuzzyJoin(table1 as table, key1 as any, table2 as table, key2 as any, optional joinKind as nullable number, optional joinOptions as nullable record) as table
=Table.FuzzyJoin(table1 as table, key1 as any, table2 as table, key2 as any, optional joinKind as nullable number, optional joinOptions as nullable record) as table
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| table1 | table | Yes | ตารางแรก (ซ้าย) ที่จะเชื่อม | |
| key1 | any | Yes | ชื่อคอลัมน์ที่ใช้เชื่อมจากตารางแรก สามารถเป็นข้อความเดียว (“ColName”) หรือลิสต์ ({“Col1”, “Col2”}) | |
| table2 | table | Yes | ตารางที่สอง (ขวา) ที่จะเชื่อม | |
| key2 | any | Yes | ชื่อคอลัมน์ที่ใช้เชื่อมจากตารางที่สอง ต้องมีจำนวนเท่ากับ key1 | |
| joinKind | nullable number | Optional | JoinKind.Inner | ประเภท Join: JoinKind.Inner, JoinKind.LeftOuter, JoinKind.RightOuter, JoinKind.FullOuter, JoinKind.LeftAnti, JoinKind.RightAnti, JoinKind.LeftSemi, JoinKind.RightSemi |
| joinOptions | nullable record | Optional | null (ค่า Default: Threshold=0.80, IgnoreCase=true, IgnoreSpace=true) | ตัวเลือก Fuzzy Matching ใน Record เช่น [IgnoreCase=true, IgnoreSpace=true, Threshold=0.8, SimilarityColumnName=”Score”] |
ใช้เชื่อมข้อมูลสินค้าหรือลูกค้าที่ชื่อสะกดไม่เหมือนกันเป๊ะๆ ระหว่างสองระบบ
ช่วยให้การ Join ไม่ล้มเหลวเพียงเพราะมีตัวอักษรผิดพลาดเล็กน้อย
let Customers = Table.FromRecords({ [ID = 1, City = "Bangkok"], [ID = 2, City = "Chiang Mai"], [ID = 3, City = "Phuket"] }), CityData = Table.FromRecords({ [Cit…let
Customers = Table.FromRecords({
[ID = 1, City = "Bangkok"],
[ID = 2, City = "Chiang Mai"],
[ID = 3, City = "Phuket"]
}),
CityData = Table.FromRecords({
[CityName = "bangkok", Region = "Central"],
[CityName = "chiang mai", Region = "North"],
[CityName = "phuket", Region = "South"]
}),
Joined = Table.FuzzyJoin(
Customers, "City",
CityData, "CityName",
JoinKind.LeftOuter,
[IgnoreCase = true]
)
in
Joined
ตารางผลลัพธ์ 3 แถว: ID, City, CityName, Region - Bangkok, Chiang Mai, Phuket จับคู่ได้สำเร็จแม้ว่า case ต่างกัน
let Products = Table.FromRecords({ [ProdID = 1, Product = "Microsoft Office"], [ProdID = 2, Product = "Google Workspace"], [ProdID = 3, Product = "Adobe Creativ…let
Products = Table.FromRecords({
[ProdID = 1, Product = "Microsoft Office"],
[ProdID = 2, Product = "Google Workspace"],
[ProdID = 3, Product = "Adobe Creative Cloud"]
}),
Inventory = Table.FromRecords({
[ItemName = "Micro soft Office", Stock = 150],
[ItemName = "Googl Workspace", Stock = 200],
[ItemName = "Adobe Creative Cloud", Stock = 50]
}),
Joined = Table.FuzzyJoin(
Products, "Product",
Inventory, "ItemName",
JoinKind.LeftOuter,
[Threshold = 0.75, IgnoreSpace = true]
)
in
Joined
ตารางผลลัพธ์: 'Microsoft Office' เข้ากับ 'Micro soft Office' แม้มีช่องว่างพิเศษ, 'Google Workspace' เข้ากับ 'Googl Workspace'
let Customers = Table.FromRecords({ [CustName = "John Smith"], [CustName = "Jane Doe"], [CustName = "Bob Wilson"] }), Orders = Table.FromRecords({ [BuyerName =…let
Customers = Table.FromRecords({
[CustName = "John Smith"],
[CustName = "Jane Doe"],
[CustName = "Bob Wilson"]
}),
Orders = Table.FromRecords({
[BuyerName = "Jon Smith", OrderID = "O1"],
[BuyerName = "Jane Do", OrderID = "O2"],
[BuyerName = "Robert Wilson", OrderID = "O3"]
}),
Joined = Table.FuzzyJoin(
Customers, "CustName",
Orders, "BuyerName",
JoinKind.LeftOuter,
[Threshold = 0.70, SimilarityColumnName = "MatchScore"]
)
in
Joined
ตารางผลลัพธ์ มีคอลัมน์ MatchScore แสดงว่า 'John Smith' เข้ากับ 'Jon Smith' ได้ 90%, 'Jane Doe' เข้า 'Jane Do' ได้ 80% เป็นต้น
let Table1 = Table.FromRecords({ [FirstName = "John", LastName = "Smith", ID = 1], [FirstName = "Jane", LastName = "Doe", ID = 2] }), Table2 = Table.FromRecords…let
Table1 = Table.FromRecords({
[FirstName = "John", LastName = "Smith", ID = 1],
[FirstName = "Jane", LastName = "Doe", ID = 2]
}),
Table2 = Table.FromRecords({
[FName = "jon", LName = "smith", Phone = "555-1234"],
[FName = "jane", LName = "do", Phone = "555-5678"]
}),
Joined = Table.FuzzyJoin(
Table1, {"FirstName", "LastName"},
Table2, {"FName", "LName"},
JoinKind.LeftOuter,
[IgnoreCase = true, Threshold = 0.80]
)
in
Joined
ตารางผลลัพธ์: แถว 1 เข้าคู่ (FirstName='John' เข้า FName='jon', LastName='Smith' เข้า LName='smith'), แถว 2 อาจไม่เข้าคู่ถ้า 'Doe' ไม่เหมือน 'do' มากพอ
ขึ้นอยู่กับกรณีการใช้งาน: 0.90 ขึ้นไป = แม่นยำสูง ยอมรับเฉพาะการสะกดผิดเล็กน้อย | 0.80 = ค่า Default ที่สมดุล | 0.70 = ยืดหยุ่นมากขึ้น ยอมรับการสะกดผิดระดับกลาง | ต่ำกว่า 0.70 = ระวัง อาจจับคู่ผิด เช่น ‘John’ เข้ากับ ‘Joan’
Table.Join ต้องการความเหมือนแบบ Exact (ตรงกันทุกตัว) ส่วน Table.FuzzyJoin ยอมรับความเหมือนแบบ Approximate (คล้ายๆกัน) ถ้าข้อมูลสะอาด Table.Join จะเร็วกว่า แต่ถ้ามีการสะกดผิดจำเป็นต้อง FuzzyJoin
เพิ่มคอลัมน์ใหม่ที่แสดงคะแนนความเหมือนจริงๆ (0.00-1.00) ช่วยให้ตรวจสอบว่า Match นั้นเชื่อถือได้แค่ไหน เช่น Match ที่ 0.95 น่าเชื่อ แต่ 0.71 ต้องสังสัย
รวมข้อความที่มีช่องว่างเกิน เช่น ‘Micro soft’ ถูกมองเป็น ‘Microsoft’ ใช้ได้ดีกับชื่อ ที่บางคนพิมพ์มีช่องว่างตรงกลาง แต่ต้องระวังกับสถานการณ์ที่ต้องรักษาช่องว่างไว้
ใช่ เพิ่ม ConcurrentRequests ให้สูงขึ้น (1-8) ทำให้การจับคู่ Fuzzy เร็วขึ้น โดยใช้หลาย thread พร้อมๆกัน เช่น ConcurrentRequests=4 จะเร็วขึ้นประมาณ 3 เท่า แต่ใช้ทรัพยากร CPU มากขึ้น
จำนวนแถวจาก table2 ที่จะจับคู่กับแถวเดียวจาก table1 ค่า Default คือ 1 (จับ 1 แถวต่อ 1 แถว) ถ้า=2 ได้ 2 แถวต่อ 1 แถว ก็จะเพิ่มแถวผลลัพธ์ไป
ระบุกฎการจับคู่ของภาษา เช่น Culture=”ja-JP” สำหรับญี่ปุ่น, “th-TH” สำหรับไทย บางภาษามีกฎการเปรียบเทียบพิเศษ เช่น ตัวอักษรลากหาง ในไทย
Table.FuzzyJoin ใช้สำหรับเชื่อม 2 ตารางเข้าด้วยกันโดยใช้ Fuzzy Matching แทนที่จะหาตัวเลขหรือตัวอักษรที่เหมือนกันเป๊ะแป๊ะ (เหมือน Table.Join) ฟังก์ชันนี้ยอมรับความเหมือน แม้จะมีการสะกดผิด ตัวพิมพ์ต่างกัน หรือช่องว่างเกินมา ซึ่งช่วยได้มากเมื่อเชื่อมข้อมูลจากหลายแหล่งที่มีคุณภาพไม่เท่ากัน
วิธีการทำงานของ Fuzzy Matching คือการเปรียบเทียบความคล้ายคลึงของข้อความ (Similarity Score) บนระดับ 0.00 ถึง 1.00 โดย 1.00 หมายถึงเหมือนกันเป๊ะ ส่วน 0.00 หมายถึงไม่เหมือนเลย ค่า Threshold ที่กำหนด (ปกติ 0.80) คือค่าต่ำสุดที่จำเป็นต้องมีเพื่อนับว่าเป็นการ Match ที่ถูกต้อง
ส่วนตัวผม Table.FuzzyJoin มักใช้ในสถานการณ์เหล่านี้:
– เชื่อมข้อมูลจากสองระบบที่มีการสะกดชื่อลูกค้าไม่เสมอกัน
– จัดการกับข้อมูลจาก CSV ที่ยูเซอร์พิมพ์มือ (ผิดบ่อย!)
– เชื่อมรหัสหรือเลขประจำตัวที่อาจพิมพ์ผิดตัวเลข
แต่ก็ต้องระวังเรื่องปลอดภัย เพราะถ้า Threshold ต่ำเกินไป อาจจับคู่ข้อมูลผิดตัวได้ เช่น ‘John’ เข้ากับ ‘Joan’ 555.