ระบุประเภทการจัดกลุ่มใน Table.Group ว่าจะใช้ Local (จัดกลุ่มแถวติดต่อกัน) หรือ Global (รวบรวมแถวทั้งหมดที่มี key เดียวกัน) ใช้เพื่อปรับประสิทธิภาพและควบคุมวิธีการจัดกลุ่มข้อมูล
=GroupKind.Local or GroupKind.Global
=GroupKind.Local or GroupKind.Global
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| GroupKind.Local | number | Optional | ค่าคงที่ (constant) ที่มีค่าเท่ากับ 0 ใช้สำหรับจัดกลุ่มแบบ Local เมื่อข้อมูลเรียงลำดับตาม key columns แล้ว (row ที่มี key เดียวกันอยู่ติดต่อกัน) จะช่วยเพิ่มประสิทธิภาพ | |
| GroupKind.Global | number | Optional | ค่าคงที่ (constant) ที่มีค่าเท่ากับ 1 ใช้เป็นค่าเริ่มต้นใน Table.Group รวบรวม row ทั้งหมดที่มี key เดียวกัน ไม่ว่าจะอยู่ตำแหน่งไหนใน table |
let SortedSales = Table.FromRecords({ [Product = "A", Sales = 100], [Product = "A", Sales = 150], [Product = "A", Sales = 200], [Product = "B", Sales = 50], [Pr…let
SortedSales = Table.FromRecords({
[Product = "A", Sales = 100],
[Product = "A", Sales = 150],
[Product = "A", Sales = 200],
[Product = "B", Sales = 50],
[Product = "B", Sales = 75]
}),
// ข้อมูล Product A อยู่ติดกัน Product B ก็อยู่ติดกัน
GroupedLocal = Table.Group(
SortedSales,
"Product",
{{"Total", each List.Sum([Sales]), type number}},
GroupKind.Local // ใช้ Local เพราะข้อมูลเรียงแล้ว
)
in
GroupedLocal
Table with 2 rows:
- [Product="A", Total=450]
- [Product="B", Total=125]
let UnsortedSales = Table.FromRecords({ [Category = "Electronics", Value = 100], [Category = "Furniture", Value = 200], [Category = "Electronics", Value = 150],…let
UnsortedSales = Table.FromRecords({
[Category = "Electronics", Value = 100],
[Category = "Furniture", Value = 200],
[Category = "Electronics", Value = 150],
[Category = "Furniture", Value = 300],
[Category = "Electronics", Value = 50]
}),
// ข้อมูล Electronics และ Furniture อยู่สลับกัน
GroupedGlobal = Table.Group(
UnsortedSales,
"Category",
{{"Total", each List.Sum([Value]), type number}}
// ไม่ระบุ groupKind = ใช้ค่าเริ่มต้น GroupKind.Global
)
in
GroupedGlobal
Table with 2 rows:
- [Category="Electronics", Total=300]
- [Category="Furniture", Total=500]
let MixedData = Table.FromRecords({ [Status = "Active", Count = 10], [Status = "Inactive", Count = 5], [Status = "Active", Count = 15], [Status = "Inactive", Co…let
MixedData = Table.FromRecords({
[Status = "Active", Count = 10],
[Status = "Inactive", Count = 5],
[Status = "Active", Count = 15],
[Status = "Inactive", Count = 3],
[Status = "Active", Count = 8]
}),
// ลอง Local (ผิด)
GroupedLocal = Table.Group(
MixedData,
"Status",
{{"Total", each List.Sum([Count]), type number}},
GroupKind.Local
),
// ลอง Global (ถูก)
GroupedGlobal = Table.Group(
MixedData,
"Status",
{{"Total", each List.Sum([Count]), type number}},
GroupKind.Global
)
in
GroupedLocal // ตรวจสอบผลลัพธ์
GroupedLocal (ผลลัพธ์ WRONG):
- [Status="Active", Total=10]
- [Status="Inactive", Total=5]
- [Status="Active", Total=23] ← เป็นกลุ่มแยกต่างหากเพราะข้อมูลไม่เรียงติดกัน
- [Status="Inactive", Total=3]
GroupedGlobal (ผลลัพธ์ CORRECT):
- [Status="Active", Total=33]
- [Status="Inactive", Total=8]
let RawData = Table.FromRecords({ [Region = "South", Sales = 100], [Region = "North", Sales = 200], [Region = "South", Sales = 150], [Region = "North", Sales =…let
RawData = Table.FromRecords({
[Region = "South", Sales = 100],
[Region = "North", Sales = 200],
[Region = "South", Sales = 150],
[Region = "North", Sales = 300],
[Region = "South", Sales = 50]
}),
// ขั้นตอน 1: เรียงลำดับตาม Region ก่อน
SortedData = Table.Sort(RawData, {{"Region", Order.Ascending}}),
// ขั้นตอน 2: จัดกลุ่มด้วย GroupKind.Local
GroupedWithLocal = Table.Group(
SortedData,
"Region",
{{"Total", each List.Sum([Sales]), type number}},
GroupKind.Local
)
in
GroupedWithLocal
Table with 2 rows:
- [Region="North", Total=500]
- [Region="South", Total=300]
นี่คือคำถามที่เจอบ่อยมากครับ และสำคัญมากเลย 🎯
.
**GroupKind.Local (ค่า = 0):**
– จัดกลุ่มจาก row ที่อยู่ติดต่อกัน
– ถ้า row ที่มี key เดียวกันแยกกันอยู่ จะถือว่าเป็นกลุ่มต่างกัน
– ประสิทธิภาพสูงเพราะต้องสแกน table น้อยลง
– ใช้ได้เมื่อข้อมูลเรียงลำดับตาม key แล้วเท่านั้น
.
**GroupKind.Global (ค่า = 1 – ค่าเริ่มต้น):**
– รวบรวมทุก row ที่มี key เดียวกัน ไม่ว่าจะอยู่ตำแหน่งไหน
– ผลลัพธ์ถูกต้องไม่ว่าข้อมูลเรียงเพียงใด
– ประสิทธิภาพต่ำกว่า Local เพราะต้องสแกน table หลายครั้ง
– ปลอดภัยกว่าสำหรับข้อมูลที่ไม่เรียงลำดับ
.
ส่วนตัวผมเลือกแบบนี้: Local ถ้าข้อมูลเรียงแล้ว Global ถ้าไม่แน่ใจ
ควรใช้ GroupKind.Local เมื่อมีเงื่อนไขครบทั้งสองข้อนี้ 🎯
.
1. **ข้อมูลเรียงลำดับตาม key columns แล้ว** – row ที่มี key เดียวกันอยู่ติดต่อกัน
2. **ต้องการประสิทธิภาพ** – โดยเฉพาะกับชุดข้อมูลขนาดใหญ่
.
ตัวอย่างที่ควรใช้ Local:
– ข้อมูลจาก SQL database ที่ query มาแล้ว เรียงลำดับ
– ข้อมูลจากไฟล์ CSV ที่มีการจัดเรียงแล้ว
– Data export จากระบบอื่นที่ guarantee ว่าเรียงลำดับ
.
ส่วนตัวผมเช็คเสมอก่อนใช้ Local ว่าข้อมูลเรียงแล้วหรือยัง ถ้าไม่แน่ใจก็ใช้ Global ปลอดภัยกว่า
จะได้ผลลัพธ์ผิด! 🚨
.
ข้อมูลจะถูกแบ่งออกเป็นกลุ่มหลายกลุ่มมากกว่าที่ควร เพราะ Local แค่จัดกลุ่มจาก row ที่ติดต่อกัน
.
ตัวอย่าง:
“`
ข้อมูล: A, B, A, B, A
Local: [A], [B], [A], [B], [A] → 5 กลุ่ม ❌
Global: [A, A, A], [B, B] → 2 กลุ่ม ✅
“`
.
นี่คือจุดที่คนทำผิดเสมอครับ ใช้ Local โดยไม่เช็คว่าข้อมูลเรียงหรือไม่ 😅
.
วิธีหลีกเลี่ยง:
1. เช็คข้อมูลก่อนเสมอว่าเรียงหรือไม่
2. ใช้ Table.Sort ก่อนจัดกลุ่มถ้าไม่แน่ใจ
3. ถ้าไม่แน่ใจ ใช้ Global แล้วเสร็จ ประหยัดเวลาดีกว่า
ขึ้นอยู่กับขนาดข้อมูลและจำนวนกลุ่มครับ 📊
.
การสแกนข้อมูล Global ต้องเช็ค row ทีละ row แล้วเทียบกับทุกกลุ่มที่มี Local แค่ต้องเทียบกับกลุ่มก่อนหน้า
.
ในการทดสอบ ผมเจอประมาณนี้:
– ข้อมูล 10,000 rows → Local ~20-30% เร็วกว่า
– ข้อมูล 100,000 rows → Local ~40-50% เร็วกว่า
– ข้อมูล 1 ล้าน rows → Local ~60% เร็วกว่า
.
แต่จำไว้ว่า ต้องใช้ Local อย่างถูกต้องเท่านั้น ถ้าข้อมูลไม่เรียง Local จะซ้ำกับ Global แล้วผิดกระทั่งเสีย
ได้ครับ! Power Query Editor ให้ตัวเลือกนี้ 🎯
.
ขั้นตอน:
1. เลือก Data → Group By (หรือ Transform → Group By)
2. ทำการตั้งค่า Group By ปกติ
3. ก่อน OK ให้ลองหาปุ่ม Advanced หรือ Options
4. จะเจอ dropdown ที่เลือก “All Rows” (= Global) หรือ “By Group” (= Local)
.
แต่บางครั้ง Microsoft ไม่โชว์ตัวเลือกนี้ใน GUI ต้องเขียน M code เอง
.
ส่วนตัวผมมักจะเขียน M code โดยตรง ได้ control มากกว่าครับ
เวลาเราใช้ Group By ใน Power Query แล้วมีการเลือกประเภทของ Grouping ที่ต่างกัน ผม็พบว่าหลายคนยังสงสัยว่าระหว่าง Local กับ Global มันต่างกันยังไง
GroupKind.Type มันคือค่าตัวเลือกที่บอกว่า “อ้อ เราต้องการจัดกลุ่มแบบไหนหว่า” นะครับ
ที่เจ๋งคือ สองแบบนี้มันจะให้ผลลัพธ์ต่างกันเลย ขึ้นอยู่กับลักษณะของข้อมูลของคุณเป็นหลัก
| ชื่อ (Name) | ค่า (Value) | คำอธิบาย |
|---|---|---|
| GroupKind.Local | 0 | จัดกลุ่มจากแถวที่อยู่ติดต่อกันใน Table เดียวกัน ถ้าค่าเปลี่ยนก็ถือว่าเป็นกลุ่มใหม่ทันที |
| GroupKind.Global | 1 | รวบรวมแถวทั้งหมดในตาราที่มีค่า Key เดียวกัน ไม่สนใจว่าพวกมันอยู่แยกกันหรือติดต่อกัน |
ส่วนตัวผมชอบใช้ Local เมื่อข้อมูลมันจัดเรียงลำดับแล้ว แต่ถ้าข้อมูลปั่นป่วน Global จะช่วยได้มากครับ 😎