Thep Excel

Table.Groupจัดกลุ่มและสรุปผลข้อมูล (Group By)

Table.Group จัดกลุ่มข้อมูลตามคอลัมน์ที่กำหนดและสรุปผลในแต่ละกลุ่มด้วย aggregation functions เช่น List.Sum, List.Count, List.Average คล้ายกับ GROUP BY ใน SQL แต่ทรงพลังกว่าเพราะสามารถจัดกลุ่มหลายคอลัมน์พร้อมกันและสร้างคอลัมน์สรุปผลหลายคอลัมน์ในคำสั่งเดียว รองรับ GroupKind.Local เพื่อเพิ่มประสิทธิภาพเมื่อข้อมูลเรียงลำดับแล้ว

fx
=Table.Group(table, key, aggregatedColumns, [groupKind], [comparer]) as table

ความนิยม9/10
ความยาก6/10
ประโยชน์9/10

อัปเดต 18 December 2025

Syntax & Arguments

อาร์กิวเมนต์ ชนิด ค่าเริ่มต้น คำอธิบาย
table table ตารางข้อมูลต้นทางที่ต้องการจัดกลุ่ม
key any ชื่อคอลัมน์ที่ใช้จัดกลุ่ม สามารถเป็น text เดี่ยว (เช่น “Category”) หรือ list ของชื่อคอลัมน์ (เช่น {“Region”, “Category”}) สำหรับจัดกลุ่มหลายระดับ
aggregatedColumns list รายการของคอลัมน์ที่ต้องการสร้างจากการสรุปผล แต่ละรายการเป็น list ที่มี 3 ส่วน: {“ชื่อคอลัมน์ใหม่”, each ฟังก์ชันสรุปผล, type ชนิดข้อมูล} เช่น {{“TotalSales”, each List.Sum([Sales]), type number}}
[groupKind]ไม่บังคับ nullable number GroupKind.Global ประเภทการจัดกลุ่ม ใช้ GroupKind.Local ถ้าข้อมูลเรียงลำดับตาม key columns แล้วเพื่อเพิ่มประสิทธิภาพ (Local group = กลุ่มที่เกิดจาก row ติดกัน, Global group = กลุ่มที่รวมทุก row ที่มี key เดียวกัน) ค่าเริ่มต้นคือ GroupKind.Global
[comparer]ไม่บังคับ nullable function null ฟังก์ชันสำหรับเปรียบเทียบค่า key ที่กำหนดเอง ถ้า comparer ถือว่า key ที่ต่างกันเป็นค่าเดียวกัน row นั้นอาจถูกจัดเข้ากลุ่มที่มีค่า key แตกต่างกัน

[ ] = อาร์กิวเมนต์ที่ไม่บังคับ

Additional Notes

Table.Group เป็นฟังก์ชันที่ผมใช้บ่อยที่สุดใน Power Query เลยครับ เพราะมันทรงพลังมากกก 😎

ฟังก์ชันนี้ใช้จัดกลุ่มข้อมูลตามคอลัมน์ที่กำหนด แล้วทำการสรุปผล (Aggregation) ในแต่ละกลุ่มได้พร้อมกันเลย เช่น หาผลรวมยอดขาย นับจำนวนรายการ หาค่าเฉลี่ย หรือหาค่าสูงสุด/ต่ำสุด

.

ถ้าเคยใช้ SQL ก็คล้ายๆ กับ GROUP BY นั่นแหละ แต่ที่เจ๋งกว่าคือ… Table.Group สามารถสร้างคอลัมน์สรุปผลหลายคอลัมน์ในคำสั่งเดียวได้เลย ไม่ต้องมาทำทีละ step 💡

.

วิธีทำงานก็คือ มันจะจัดกลุ่ม row ที่มีค่าเหมือนกันในคอลัมน์ที่กำหนดเข้าด้วยกัน จากนั้นสร้าง record ใหม่สำหรับแต่ละกลุ่มที่ประกอบด้วยค่าของ key columns และคอลัมน์สรุปผลที่คำนวณจากข้อมูลในกลุ่มนั้น

.

สามารถใช้ร่วมกับฟังก์ชัน aggregation อื่นๆ ได้สารพัด:

  • List.Sum สำหรับหาผลรวม
  • List.Count สำหรับนับจำนวน
  • List.Average สำหรับหาค่าเฉลี่ย
  • List.Min และ List.Max สำหรับหาค่าต่ำสุด/สูงสุด
  • Table.RowCount สำหรับนับจำนวน row ในแต่ละกลุ่ม

.

ที่สำคัญอีกอย่างคือ… ถ้าข้อมูลเรียงลำดับตาม key columns อยู่แล้ว สามารถระบุ GroupKind.Local เพื่อเพิ่มประสิทธิภาพได้เลย ส่วนตัวผมใช้เทคนิคนี้กับข้อมูลขนาดใหญ่แล้วช่วยได้เยอะครับ ⚡

How it works

สรุปยอดขายตามสาขา

จัดกลุ่มข้อมูลการขายตามสาขาและหาผลรวมยอดขาย ค่าเฉลี่ยต่อรายการ และจำนวนรายการในแต่ละสาขา

วิเคราะห์ข้อมูลลูกค้า

นับจำนวนคำสั่งซื้อต่อลูกค้า หามูลค่ารวมและค่าเฉลี่ยต่อคำสั่งซื้อเพื่อวิเคราะห์พฤติกรรมการซื้อ

รายงานตามหมวดหมู่และระยะเวลา

จัดกลุ่มข้อมูลตามหลายมิติพร้อมกัน เช่น หมวดหมู่สินค้าและเดือน เพื่อสร้างรายงานยอดขายแบบสรุป

หาค่าสถิติต่อกลุ่ม

คำนวณค่าสูงสุด ต่ำสุด ค่าเฉลี่ย และส่วนเบี่ยงเบนมาตรฐานของข้อมูลในแต่ละกลุ่ม

Examples

ตัวอย่างที่ 1: จัดกลุ่มพื้นฐานและหาผลรวมlet Sales = Table.FromRecords({ [Category = "Electronics", Amount = 500], [Category = "Electronics", Amount = 800], [Category = "Furniture", Amount = 1200], [Ca…

จัดกลุ่มข้อมูลการขายตาม Category และใช้ List.Sum หาผลรวมของ Amount ในแต่ละกลุ่ม ผลลัพธ์จะมี 1 row สำหรับแต่ละหมวดหมู่ที่แสดงยอดรวมทั้งหมด

สังเกตว่า Table.Group ใช้ each keyword เพื่ออ้างถึงแต่ละกลุ่มของข้อมูล ส่วน [Amount] จะเป็น list ของค่าทั้งหมดในคอลัมน์ Amount ภายในกลุ่มนั้น นี่เป็นจุดสำคัญที่ต้องเข้าใจครับ

fx
let
Sales = Table.FromRecords({
[Category = "Electronics", Amount = 500],
[Category = "Electronics", Amount = 800],
[Category = "Furniture", Amount = 1200],
[Category = "Furniture", Amount = 600]
}),
GroupedSales = Table.Group(
Sales,
"Category",
{{"TotalAmount", each List.Sum([Amount]), type number}}
)
in
GroupedSales

ผลลัพธ์Table with 2 rows:
– [Category="Electronics", TotalAmount=1300]
– [Category="Furniture", TotalAmount=1800]
ตัวอย่างที่ 2: สร้างหลายคอลัมน์สรุปผลพร้อมกันlet Orders = Table.FromRecords({ [CustomerID = 1, OrderValue = 100], [CustomerID = 1, OrderValue = 150], [CustomerID = 2, OrderValue = 200], [CustomerID = 2, Or…

นี่คือจุดเด่นของ Table.Group ครับ เราสามารถสร้างคอลัมน์สรุปผลหลายคอลัมน์ในคราวเดียวได้เลย 😎

สังเกตว่าเราใช้ Table.RowCount(_) เพื่อนับจำนวนคำสั่งซื้อ โดย _ หมายถึง table ของกลุ่มนั้นทั้งหมด จากนั้นก็ใช้ List.Sum สำหรับผลรวม List.Average สำหรับค่าเฉลี่ย และ List.Max สำหรับค่าสูงสุด

การรวม aggregation functions หลายตัวแบบนี้ช่วยให้เราวิเคราะห์ข้อมูลได้ครอบคลุมในขั้นตอนเดียว ไม่ต้องมาทำทีละคอลัมน์

fx
let
Orders = Table.FromRecords({
[CustomerID = 1, OrderValue = 100],
[CustomerID = 1, OrderValue = 150],
[CustomerID = 2, OrderValue = 200],
[CustomerID = 2, OrderValue = 300],
[CustomerID = 2, OrderValue = 100]
}),
CustomerSummary = Table.Group(
Orders,
"CustomerID",
{
{"TotalOrders", each Table.RowCount(_), Int64.Type},
{"TotalValue", each List.Sum([OrderValue]), type number},
{"AverageValue", each List.Average([OrderValue]), type number},
{"MaxValue", each List.Max([OrderValue]), type number}
}
)
in
CustomerSummary

ผลลัพธ์Table with 2 rows:
– [CustomerID=1, TotalOrders=2, TotalValue=250, AverageValue=125, MaxValue=150]
– [CustomerID=2, TotalOrders=3, TotalValue=600, AverageValue=200, MaxValue=300]
ตัวอย่างที่ 3: จัดกลุ่มด้วยหลายคอลัมน์พร้อมกันlet RegionalSales = Table.FromRecords({ [Region = "North", Product = "A", Sales = 100], [Region = "North", Product = "A", Sales = 200], [Region = "North", Produ…

การจัดกลุ่มตามหลายคอลัมน์พร้อมกันเป็นเทคนิคที่ใช้บ่อยมากครับ เราแค่ใส่ list ของชื่อคอลัมน์ {"Region", "Product"} แทนที่จะใส่คอลัมน์เดียว

ผลลัพธ์ที่ได้จะแยกตามทั้งภูมิภาคและสินค้า ซึ่งเป็นรูปแบบ multi-dimensional grouping ที่เจอบ่อยในการวิเคราะห์ข้อมูล ส่วนตัวผมใช้เทคนิคนี้เวลาต้องทำรายงานยอดขายแยกตามหลายมิติครับ 💡

fx
let
RegionalSales = Table.FromRecords({
[Region = "North", Product = "A", Sales = 100],
[Region = "North", Product = "A", Sales = 200],
[Region = "North", Product = "B", Sales = 150],
[Region = "South", Product = "A", Sales = 300],
[Region = "South", Product = "B", Sales = 250]
}),
GroupedByRegionProduct = Table.Group(
RegionalSales,
{"Region", "Product"},
{
{"TotalSales", each List.Sum([Sales]), type number},
{"TransactionCount", each List.Count([Sales]), Int64.Type}
}
)
in
GroupedByRegionProduct

ผลลัพธ์Table with 3 rows:
– [Region="North", Product="A", TotalSales=300, TransactionCount=2]
– [Region="North", Product="B", TotalSales=150, TransactionCount=1]
– [Region="South", Product="A", TotalSales=300, TransactionCount=1]
ตัวอย่างที่ 4: ใช้ GroupKind.Local เพื่อเพิ่มประสิทธิภาพlet SortedData = Table.FromRecords({ [Status = "Active", Value = 100], [Status = "Active", Value = 200], [Status = "Active", Value = 150], [Status = "Inactive",…

นี่เป็น performance trick ที่หลายคนไม่รู้จักครับ 😎

เมื่อข้อมูลเรียงลำดับตาม key columns แล้ว (row ที่มี key เดียวกันอยู่ติดกัน) การใช้ GroupKind.Local จะช่วยเพิ่มประสิทธิภาพได้มากเพราะ Power Query ไม่ต้องสแกนทั้ง table เพื่อหา row ที่มี key เดียวกัน

Local group = กลุ่มที่เกิดจาก row ติดกัน
Global group (ค่าเริ่มต้น) = รวมทุก row ที่มี key เดียวกันทั้ง table ไม่ว่าจะอยู่ตำแหน่งไหน

ถ้าทำงานกับข้อมูลขนาดใหญ่ เทคนิคนี้ช่วยได้เยอะครับ

fx
let
SortedData = Table.FromRecords({
[Status = "Active", Value = 100],
[Status = "Active", Value = 200],
[Status = "Active", Value = 150],
[Status = "Inactive", Value = 50],
[Status = "Inactive", Value = 75]
}),
// ข้อมูลเรียงลำดับตาม Status แล้ว (Active ติดกันหมด, Inactive ติดกันหมด)
GroupedWithLocal = Table.Group(
SortedData,
"Status",
{{"Total", each List.Sum([Value]), type number}},
GroupKind.Local // ระบุว่าข้อมูลเรียงลำดับแล้ว
)
in
GroupedWithLocal

ผลลัพธ์Table with 2 rows:
– [Status="Active", Total=450]
– [Status="Inactive", Total=125]
ตัวอย่างที่ 5: ใช้ร่วมกับ Table.SelectRows และ List.Accumulatelet TransactionData = Table.FromRecords({ [Date = #date(2024, 1, 15), Category = "A", Amount = 100], [Date = #date(2024, 1, 20), Category = "A", Amount = 200],…

ตัวอย่างนี้แสดงการผสม Table.Group กับฟังก์ชันอื่นๆ ครับ

ก่อนอื่นเราใช้ Table.SelectRows กรองเฉพาะข้อมูลที่ต้องการก่อนจัดกลุ่ม จากนั้นภายใน aggregatedColumns เราใช้ List.Accumulate เพื่อคำนวณ running total (ผลรวมสะสม)

ใน case นี้ List.Sum กับ List.Accumulate ให้ผลเหมือนกัน แต่ List.Accumulate ยืดหยุ่นกว่ามากสำหรับการคำนวณที่ซับซ้อน เช่น ผลคูณสะสม หรือการคำนวณที่ขึ้นกับค่าก่อนหน้า

เทคนิคนี้มีประโยชน์เวลาต้องทำ custom aggregation ที่ Power Query ไม่มีฟังก์ชันสำเร็จรูปให้ครับ 💡

fx
let
TransactionData = Table.FromRecords({
[Date = #date(2024, 1, 15), Category = "A", Amount = 100],
[Date = #date(2024, 1, 20), Category = "A", Amount = 200],
[Date = #date(2024, 2, 10), Category = "B", Amount = 150],
[Date = #date(2024, 2, 25), Category = "B", Amount = 300]
}),
// ขั้นตอน 1: กรองเฉพาะเดือนมกราคม
JanuaryOnly = Table.SelectRows(
TransactionData,
each Date.Month([Date]) = 1
),
// ขั้นตอน 2: จัดกลุ่มและสรุปผล
GroupedByCategory = Table.Group(
JanuaryOnly,
"Category",
{
{"TotalAmount", each List.Sum([Amount]), type number},
{"RunningTotal", each List.Accumulate([Amount], 0, (state, current) => state + current), type number}
}
)
in
GroupedByCategory

ผลลัพธ์Table with 1 row:
– [Category="A", TotalAmount=300, RunningTotal=300]

FAQs

ความแตกต่างระหว่าง Table.Group และ Table.AggregateTableColumn คืออะไร?+

คำถามนี้เจอบ่อยมากครับ เพราะทั้งสองตัวดูคล้ายกัน 😅

Table.Group ใช้สำหรับจัดกลุ่มข้อมูลจาก flat table และสร้างคอลัมน์สรุปผลใหม่ในขั้นตอนเดียว

ส่วน Table.AggregateTableColumn ใช้เมื่อมีคอลัมน์ที่เป็น nested table อยู่แล้ว และต้องการ aggregate ข้อมูลจาก nested table นั้น

พูดง่ายๆ คือ Table.Group สร้างการจัดกลุ่มขึ้นมาใหม่ ขณะที่ Table.AggregateTableColumn ทำงานกับโครงสร้างที่มีอยู่แล้ว

ทำไม Table.RowCount(_) ใช้ _ แทน [ColumnName]?+

นี่เป็นจุดที่หลายคนงงกันครับ 😅

เพราะ Table.RowCount รับ table เป็น argument ไม่ใช่ list ดังนั้น _ จึงหมายถึง table ของกลุ่มนั้นทั้งหมด

ส่วน [ColumnName] จะให้ list ของค่าในคอลัมน์นั้น ถ้าใช้ List.Count([ColumnName]) จะนับจำนวน element ใน list ขณะที่ Table.RowCount(_) จะนับจำนวน row ทั้งหมดใน table ของกลุ่มนั้น

ง่ายๆ คือ _ = table, [ColumnName] = list ครับ

GroupKind.Local ควรใช้เมื่อไหร่?+

ใช้ GroupKind.Local เมื่อข้อมูลเรียงลำดับตาม key columns แล้ว (row ที่มี key เดียวกันอยู่ติดกัน) จะช่วยเพิ่มประสิทธิภาพได้มากเพราะ Power Query ไม่ต้องสแกนทั้ง table

แต่ถ้าข้อมูลยังไม่เรียงลำดับ ต้องใช้ค่าเริ่มต้น (GroupKind.Global) หรือเรียงลำดับด้วย Table.Sort ก่อนครับ

ส่วนตัวผมจะเช็คก่อนเสมอว่าข้อมูลเรียงอยู่แล้วหรือเปล่า ถ้าเรียงแล้วก็ใส่ GroupKind.Local เลย เพราะช่วยได้เยอะถ้าข้อมูลเยอะ 💡

สามารถใช้ custom function ใน aggregatedColumns ได้หรือไม่?+

ได้สิครับ นี่แหละที่ทำให้ Table.Group ทรงพลัง! 😎

คุณสามารถเขียน custom function ภายใน each ได้ เช่น:
– each List.Sum(List.Select([Amount], each _ > 100)) → หาผลรวมเฉพาะค่าที่มากกว่า 100
– each List.Accumulate(…) → คำนวณ running total หรือผลคูณสะสม
– each List.Max([Price]) – List.Min([Price]) → หาช่วงของราคา

เทคนิคนี้ทำให้เราวิเคราะห์ข้อมูลได้แบบ custom ตามที่ต้องการเลยครับ

ทำไมผลลัพธ์จาก Table.Group ไม่เรียงลำดับ?+

เคยเจอมั้ยครับที่ group แล้วลำดับมันไม่เป็นที่? 😅

ตาม Microsoft Learn ระบุไว้ว่า Table.Group ไม่รับประกันว่าผลลัพธ์จะเรียงลำดับแบบใดแบบหนึ่ง

ถ้าต้องการให้ผลลัพธ์เรียงลำดับ ต้องใช้ Table.Sort หลังจาก Table.Group เสมอ เช่น:
Table.Sort(GroupedTable, "Category")

ผมแนะนำให้ทำเป็นนิสัยเลยครับ group แล้วก็ sort ตาม เพราะไม่งั้นลำดับมันอาจไม่เป็นที่คาดหวัง

สามารถใช้ Table.Group กับข้อมูลที่มี null values ได้ไหม?+

ได้ครับ แต่ต้องระวังเรื่อง null นิดนึง 💡

Aggregation functions บางตัวจัดการ null แตกต่างกัน:
– List.Sum และ List.Average จะข้าม null values โดยอัตโนมัติ
– List.Count นับทุกค่า รวม null ด้วย
– List.NonNullCount นับเฉพาะค่าที่ไม่ใช่ null

ถ้าไม่แน่ใจว่า null จะส่งผลมั้ย แนะนำให้ใช้ List.Select กรอง null ออกก่อนทำการคำนวณจะปลอดภัยกว่าครับ

Resources & Related

ฟังก์ชันที่ผู้เขียนโยงไว้กับ Table.Group จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง

ฟังก์ชันนี้Table.GroupTable functions
Table functions (8)
Table.AddFuzzyClusterColumn

Table.AddFuzzyClusterColumn เพิ่มคอลัมน์ใหม่ที่มีค่าตัวแทนสำหรับแต่ละกลุ่ม โดยจับคู่ข้อมูลที่คล้ายกัน แม้จะมีข้อความที่ต่างกัน เช่น การสะกด ตัวอักษรพิมพ์ใหญ่-เล็ก หรือช่องว่าง

Table.Distinct

Table.Distinct ลบแถวที่ซ้ำกันออกจากตารางตามคอลัมน์ที่กำหนด หรือทั้งตารางถ้าไม่ระบุคอลัมน์

Table.ExpandTableColumn

Table.ExpandTableColumn ใช้แตกข้อมูลจากคอลัมน์ที่เป็น nested table ออกมาเป็นคอลัมน์และแถวปกติในตารางหลัก โดยรักษาข้อมูลคอลัมน์อื่นไว้ และทำซ้ำแถวหลักสำหรับแต่ละแถวในตารางซ้อน มักใช้คู่กับ Table.NestedJoin หลัง join ตาราง หรือใช้ขยายข้อมูลจากแหล่งที่มีโครงสร้างแบบ hierarchical เช่น JSON หรือ API

Table.Pivot

Table.Pivot แปลงข้อมูล long format (แนวตั้ง) เป็น wide format (แนวนอน) โดยหมุนค่า attribute ให้เป็นคอลัมน์ใหม่

Table.RowCount

ฟังก์ชันสำหรับนับจำนวนแถวทั้งหมดในตาราง โดยคืนค่าเป็นตัวเลขครับ

Table.SelectRows

Table.SelectRows เป็นฟังก์ชันสำหรับกรองตาราง (filter table) ใน Power Query โดยใช้ฟังก์ชันเงื่อนไข (condition function) เพื่อตรวจสอบแต่ละแถว ถ้าเงื่อนไขคืนค่า true จะเก็บแถวนั้นไว้ ถ้าเป็น false จะตัดทิ้ง สามารถใช้ keyword 'each' ร่วมกับการอ้างอิงคอลัมน์ด้วย [ColumnName] เพื่อเขียนเงื่อนไขได้สะดวก รองรับการกรองตามตัวเลข ข้อความ วันที่ การตรวจสอบค่า null และเงื่อนไขที่ซับซ้อนด้วย and/or operators ฟังก์ชันนี้รองรับ Query Folding ซึ่งช่วยเพิ่มประสิทธิภาพเมื่อทำงานกับ data source ขนาดใหญ่

Table.Sort

เรียงลำดับข้อมูลในตารางตามคอลัมน์ที่ระบุ รองรับการเรียงหลายระดับและกำหนดทิศทางการเรียง

Table.Split

แบ่งตารางออกเป็นรายการของตารางย่อยตามจำนวนแถวที่กำหนด เหมาะสำหรับ Pagination และ Batch Processing

enumerations (2)
GroupKind.Type

ระบุประเภทการจัดกลุ่มใน Table.Group ว่าจะใช้ Local (จัดกลุ่มแถวติดต่อกัน) หรือ Global (รวบรวมแถวทั้งหมดที่มี key เดียวกัน) ใช้เพื่อปรับประสิทธิภาพและควบคุมวิธีการจัดกลุ่มข้อมูล

JoinKind.Type

JoinKind.Type คือ enum ที่ระบุประเภทของการ Join (Inner, Outer, Anti, Semi) เมื่อรวมตารางข้อมูลสองตาราง ใช้กับ Table.Join เพื่อควบคุมว่าแถวไหนจะปรากฏในผลลัพธ์

List functions (1)
List.Mode

List.Mode หาค่าที่ปรากฏบ่อยที่สุดในรายการ (Mode คือค่าที่เกิดขึ้นมากที่สุด) ใช้สำหรับการวิเคราะห์ข้อมูล สถิติ และการหาแนวโน้มกลาง

Comments

อีเมลของคุณจะไม่ถูกเผยแพร่