---
title: GROUPBY – จัดกลุ่มและคำนวณแบบละเอียด
url: https://www.thepexcel.com/functions/dax/table-manipulation/groupby-dax/
type: function-explainer
program: DAX
syntax: "GROUPBY(<Table>, [<GroupBy_ColumnName>], [<Name>], [<Expression>])"
date: 2025-12-13
updated: 2025-12-23
scores:
  popularity: 6
  difficulty: 6
  usefulness: 6
---

# GROUPBY – จัดกลุ่มและคำนวณแบบละเอียด

> GROUPBY สร้างตารางสรุปโดยจัดกลุ่มตามคอลัมน์ที่กำหนด และเพิ่มคอลัมน์คำนวณแบบกลุ่มต่อกลุ่มได้ โดยใช้ C

## คำอธิบาย

GROUPBY สร้างตารางสรุปโดยจัดกลุ่มตามคอลัมน์ที่กำหนด และเพิ่มคอลัมน์คำนวณแบบกลุ่มต่อกลุ่มได้ โดยใช้ CURRENTGROUP() เข้าถึงแถวภายในกลุ่ม เหมาะกับการคำนวณซ้อนหรือคำนวณจากคอลัมน์ชั่วคราว (local columns)

## Syntax

```excel
GROUPBY(&lt;Table&gt;, [&lt;GroupBy_ColumnName&gt;], [&lt;Name&gt;], [&lt;Expression&gt;])
```

**Variant**

```excel
GROUPBY(&lt;Table&gt;, &lt;GroupBy_ColumnName&gt;)
```

สร้างตารางที่จัดกลุ่มตามคอลัมน์ที่ระบุ

**Variant**

```excel
GROUPBY(&lt;Table&gt;, &lt;GroupBy_ColumnName&gt;, &lt;Name&gt;, &lt;Expression&gt;)
```

เพิ่มคอลัมน์คำนวณต่อกลุ่ม (มักใช้ CURRENTGROUP ภายใน Expression)

## Arguments

| Name | Required | Type | Default | Description |
| --- | --- | --- | --- | --- |
| Table | Yes | Table |  | ตารางต้นทางที่ต้องการจัดกลุ่ม (อาจเป็นตารางจาก model หรือตารางชั่วคราวจาก DAX ก็ได้) |
| GroupBy_ColumnName | No | Column | ไม่มี | คอลัมน์ที่ใช้จัดกลุ่ม (สามารถระบุหลายคอลัมน์ได้ตามต้องการ) - ถ้าไม่ระบุเลยจะได้ตารางแถวเดียว |
| Name | No | String | ไม่มี | ชื่อคอลัมน์ใหม่ที่ต้องการเพิ่มเข้าตารางผลลัพธ์ (เป็น String ต้องใส่ใน "...") |
| Expression | No | Expression | ไม่มี | นิพจน์ที่ใช้คำนวณค่าสำหรับคอลัมน์ใหม่ (ควรใช้ CURRENTGROUP() ร่วมกับ iterator เช่น SUMX, MAXX, COUNTROWS) |

## เคสการใช้งาน

### สรุปยอดหรือจำนวนต่อกลุ่ม

เช่น ยอดรวมต่อ CustomerID หรือจำนวนแถวต่อกลุ่ม

_เหมาะกับ:_ group-summary

### คำนวณค่าต่อกลุ่มด้วย iterator

เช่น MAXX/MINX/SUMX ภายในกลุ่มผ่าน CURRENTGROUP

_เหมาะกับ:_ group-iterator

## ตัวอย่าง

### 1. ตัวอย่างที่ 1: จัดกลุ่มพื้นฐาน - ยอดรวมต่อลูกค้า

```excel
Sales By Customer =
GROUPBY(
    Sales,
    Sales[CustomerID],
    "Total Sales", SUMX(CURRENTGROUP(), Sales[Amount])
)
```

**ผลลัพธ์:** `ตารางที่มี CustomerID และ Total Sales (ยอดรวมต่อลูกค้า)`

GROUPBY จัดกลุ่มตาราง Sales ตาม CustomerID แล้วใช้ SUMX ร่วมกับ CURRENTGROUP() เพื่อรวมยอด Amount ของทุกแถวในกลุ่มนั้น โดย CURRENTGROUP() คืนค่าเป็นตารางย่อยของแถวในกลุ่ม

Context: Sales มีคอลัมน์ CustomerID และ Amount

### 2. ตัวอย่างที่ 2: จัดกลุ่มหลายคอลัมน์ - นับจำนวนธุรกรรม

```excel
Transaction Count =
GROUPBY(
    Sales,
    Sales[CustomerID],
    Sales[ProductID],
    "Transaction Count", COUNTROWS(CURRENTGROUP())
)
```

**ผลลัพธ์:** `ตารางแสดงจำนวนธุรกรรมแยกตาม CustomerID และ ProductID`

จัดกลุ่มตามสองคอลัมน์พร้อมกัน (CustomerID และ ProductID) แล้วใช้ COUNTROWS(CURRENTGROUP()) นับจำนวนแถวในแต่ละกลุ่ม ผลลัพธ์จะบอกว่าลูกค้าแต่ละคนซื้อสินค้าแต่ละชนิดกี่ครั้ง

Context: Sales มีคอลัมน์ CustomerID, ProductID

### 3. ตัวอย่างที่ 3: หลายคอลัมน์คำนวณในครั้งเดียว

```excel
Sales Summary =
GROUPBY(
    Sales,
    Sales[CustomerID],
    "Total Sales", SUMX(CURRENTGROUP(), Sales[Amount]),
    "Avg Sales", AVERAGEX(CURRENTGROUP(), Sales[Amount]),
    "Max Sales", MAXX(CURRENTGROUP(), Sales[Amount])
)
```

**ผลลัพธ์:** `ตารางสรุปที่มีทั้งยอดรวม, ค่าเฉลี่ย, และค่าสูงสุดต่อลูกค้า`

GROUPBY สามารถเพิ่มหลายคอลัมน์คำนวณในครั้งเดียวได้ โดยแต่ละคอลัมน์ใช้ CURRENTGROUP() อ้างอิงกลุ่มเดียวกัน ซึ่งประหยัดกว่าการเรียก GROUPBY หลายรอบ

Context: Sales มีคอลัมน์ CustomerID, Amount

### 4. ตัวอย่างที่ 4: Nested Grouping - คำนวณซ้อนชั้น

```excel
Max Avg Price By Category =
VAR SubcategoryAvg =
    GROUPBY(
        Product,
        Product[Category],
        Product[Subcategory],
        "Avg Price", AVERAGEX(CURRENTGROUP(), Product[Price])
    )
VAR MaxByCategory =
    GROUPBY(
        SubcategoryAvg,
        [Category],
        "Max Subcategory Avg", MAXX(CURRENTGROUP(), [Avg Price])
    )
RETURN
    MaxByCategory
```

**ผลลัพธ์:** `ตารางแสดงค่าเฉลี่ยราคาสูงสุดของ Subcategory ในแต่ละ Category`

นี่คือกรณีที่ GROUPBY เหนือกว่า SUMMARIZE อย่างชัดเจน! เราจัดกลุ่มสองชั้น:
1. กลุ่มย่อยระดับ Category + Subcategory หาค่าเฉลี่ยราคา (สร้าง local column [Avg Price])
2. จัดกลุ่มใหญ่ระดับ Category หาค่าสูงสุดจาก [Avg Price] ที่คำนวณไว้

ถ้าใช้ SUMMARIZE จะทำไม่ได้ เพราะมันรวบรวม (aggregate) คอลัมน์ชั่วคราวไม่ได้ ต้องใช้ GROUPBY กับ CURRENTGROUP() เท่านั้น

Context: Product มีคอลัมน์ Category, Subcategory, Price

### 5. ตัวอย่างที่ 5: จัดกลุ่มโดยไม่ระบุคอลัมน์ - คำนวณทั้งตาราง

```excel
Overall Stats =
GROUPBY(
    Sales,
    "Total Amount", SUMX(CURRENTGROUP(), Sales[Amount]),
    "Row Count", COUNTROWS(CURRENTGROUP())
)
```

**ผลลัพธ์:** `ตารางแถวเดียวที่มียอดรวมทั้งหมดและจำนวนแถวทั้งหมด`

ถ้าไม่ระบุ GroupBy_ColumnName เลย GROUPBY จะคำนวณทั้งตาราง (ได้ตารางแถวเดียว) คล้ายการ aggregate ทั้งหมดโดยไม่แบ่งกลุ่ม ใช้ได้เมื่อต้องการคำนวณหลายค่าจากตารางพร้อมกัน

Context: Sales มีคอลัมน์ Amount

## หมายเหตุเพิ่มเติม

- GROUPBY ออกแบบมาให้ใช้กับ CURRENTGROUP() เสมอ - ห้ามเขียน Expression โดยไม่ใช้ CURRENTGROUP() เพราะอาจได้ผลลัพธ์ผิดพลาด

- ใช้ GROUPBY กับตารางเล็กๆ หรือตารางชั่วคราว (local tables) เพราะมัน materialize ข้อมูลทั้งหมดที่ formula engine ซึ่งช้ากว่า SUMMARIZE ที่ใช้ storage engine

- Nested grouping แบบมืออาชีพ: ใช้ SUMMARIZE ชั้นใน (เร็ว) แล้วใช้ GROUPBY ชั้นนอก (ยืดหยุ่น) เพื่อคำนวณจากคอลัมน์ชั่วคราว

- GROUPBY ห้ามใช้ CALCULATE ภายใน Expression เพราะไม่มี context transition - ถ้าต้องการ CALCULATE ให้ใช้ SUMMARIZE หรือ ADDCOLUMNS แทน

- GROUPBY จะลบแถวที่มีผลลัพธ์เป็น blank จาก CURRENTGROUP() โดยอัตโนมัติ ต้องระวังถ้าต้องการให้แสดงทุกกลุ่ม (รวม blank)

- เวลาต้องการเพิ่มหลายคอลัมน์คำนวณ ใส่ใน GROUPBY เดียวกันเลย (ระบุ Name-Expression ซ้ำๆ) ดีกว่าเรียก GROUPBY หลายครั้ง

- ถ้าจะคำนวณทั้งตารางไม่แบ่งกลุ่ม (aggregate ทั้งหมด) ให้ข้าม GroupBy_ColumnName ไปเลย จะได้ตารางแถวเดียว

## คำถามที่พบบ่อย

**Q: GROUPBY ต่างจาก SUMMARIZE อย่างไร?**

ต่างกันทั้งประสิทธิภาพและความสามารถ:
• SUMMARIZE ใช้เทคนิค "clustering" ที่ส่งคำสั่งไปทำที่ storage engine (VertiPaq) เลย จึงเร็วกว่าเมื่อจัดกลุ่มตามคอลัมน์ใน model แต่จัดการคอลัมน์ชั่วคราว (local columns) ได้ไม่ดี และอาจให้ผลลัพธ์ไม่ตรงความตั้งใจในบางกรณี
• GROUPBY ทำงานที่ formula engine หลังจาก materialize ตารางมาแล้ว ช้ากว่าเมื่อจัดกลุ่มตามคอลัมน์ใน model แต่จัดการคอลัมน์ชั่วคราวได้ดี และต้องใช้ CURRENTGROUP() เสมอ

หลักง่ายๆ: ใช้ SUMMARIZE กับคอลัมน์จริง, ใช้ GROUPBY กับคอลัมน์ชั่วคราว

**Q: ทำไมต้องใช้ CURRENTGROUP() เสมอใน Expression?**

เพราะ GROUPBY ถูกออกแบบมาให้ทำงานกับ CURRENTGROUP() โดยเฉพาะ ถ้าเขียน Expression โดยไม่ใช้ CURRENTGROUP() อาจได้ผลลัพธ์ไม่ตรงตามที่คาดหวัง หรือ error ในบาง DAX version เพราะ Microsoft เปลี่ยนพฤติกรรมของ GROUPBY ให้รองรับเฉพาะ CURRENTGROUP() เท่านั้น

CURRENTGROUP() คือ "ตัวแทน" ของแถวทั้งหมดในกลุ่มนั้นๆ ที่ iterator function (SUMX, MAXX, ฯลฯ) ต้องการใช้

**Q: GROUPBY ใช้ CALCULATE ได้ไหม?**

ใช้ไม่ได้! เพราะ Expression ใน GROUPBY ทำงานแบบ row-by-row iteration โดยไม่มี context transition ที่ CALCULATE ต้องการ ถ้าพยายามใส่ CALCULATE จะได้ error หรือผลลัพธ์ผิดพลาด

ถ้าต้องการ context transition ให้ใช้ SUMMARIZE หรือ ADDCOLUMNS แทน

**Q: Nested Grouping ควรใช้อะไร?**

ใช้แบบผสม เพื่อให้ได้ทั้งประสิทธิภาพและความยืดหยุ่น:
1. ใช้ SUMMARIZE จัดกลุ่มชั้นในก่อน (จากตารางใน model) → เร็ว
2. ใช้ GROUPBY จัดกลุ่มชั้นนอก (จากตารางชั่วคราว) → คำนวณคอลัมน์ชั่วคราวได้

ตัวอย่าง:
VAR InnerGroup = SUMMARIZE(Sales, Sales[Category], Sales[Subcategory])
VAR OuterCalc = GROUPBY(InnerGroup, [Category], "Max", MAXX(CURRENTGROUP(), ...))

วิธีนี้หลีกเลี่ยงการ materialize ตารางใหญ่ด้วย GROUPBY ตั้งแต่แรก

**Q: ประสิทธิภาพของ GROUPBY เป็นอย่างไร?**

GROUPBY ไม่ได้ใช้ VertiPaq storage engine เหมือน SUMMARIZE ทำให้ช้ากว่าเมื่อจัดกลุ่มตารางใหญ่ๆ จาก model เพราะต้อง materialize (โหลดข้อมูลมาเก็บในหน่วยความจำ formula engine) ทั้งหมด

ข้อแนะนำ:
• ใช้ GROUPBY กับตารางที่ผ่านการกรองหรือลดขนาดแล้ว (เล็กลง)
• ไม่ควรใช้ GROUPBY กับตาราง fact ขนาดใหญ่โดยตรง ให้ใช้ SUMMARIZE ลดขนาดก่อน
• เมื่อจำเป็นต้องใช้ GROUPBY ให้เก็บผลลัพธ์ไว้ใน VAR แล้วใช้ซ้ำ (ไม่ต้องคำนวณซ้ำ)

## แหล่งข้อมูลเพิ่มเติม

- [DAX Guide: GROUPBY](https://dax.guide/groupby/) _(guide)_
- [SQLBI: Differences between GROUPBY and SUMMARIZE](https://www.sqlbi.com/articles/differences-between-groupby-and-summarize/) _(guide)_
- [SQLBI: Nested grouping using GROUPBY vs SUMMARIZE](https://www.sqlbi.com/articles/nested-grouping-using-groupby-vs-summarize/) _(guide)_
- [Microsoft Learn: GROUPBY function (DAX)](https://learn.microsoft.com/en-us/dax/groupby-function-dax) _(official)_

---

_Source: [https://www.thepexcel.com/functions/dax/table-manipulation/groupby-dax/](https://www.thepexcel.com/functions/dax/table-manipulation/groupby-dax/)_
