---
title: SUMMARIZE – จัดกลุ่มข้อมูลและสร้างตารางสรุป (Table Grouping)
url: https://www.thepexcel.com/functions/dax/table-manipulation/summarize-dax/
type: function-explainer
program: DAX
syntax: "SUMMARIZE(<table>, <groupBy_columnName>[, <groupBy_columnName>]...)"
date: 2025-12-19
scores:
  popularity: 8
  difficulty: 6
  usefulness: 8
---

# SUMMARIZE – จัดกลุ่มข้อมูลและสร้างตารางสรุป (Table Grouping)

> จัดกลุ่มข้อมูลและสร้างตารางสรุป (คล้าย GROUP BY ใน SQL)

## คำอธิบาย

SUMMARIZE สร้างตารางสรุปโดยจัดกลุ่มข้อมูลตามคอลัมน์ที่กำหนด คล้าย GROUP BY ใน SQL หรือ Pivot Table ใน Excel คืนค่าตารางที่มีหนึ่งแถวต่อหนึ่ง unique combination ของคอลัมน์ที่เลือก สามารถอ้างถึงคอลัมน์จาก related table ได้โดยตรงโดยไม่ต้องใช้ RELATED มักใช้สร้าง virtual table ใน measure เพื่อทำ intermediate calculations ก่อนใช้ iterator functions อย่าง SUMX, AVERAGEX คำนวณต่อ ⚠️ Best Practice: ใช้ ADDCOLUMNS ครอบ SUMMARIZE แทนการใส่ extension columns ตรงๆ เพื่อ performance และ filter context control ที่ดีกว่า สำหรับ calculated table แนะนำใช้ SUMMARIZECOLUMNS แทนเนื่องจากมี performance ดีกว่าอย่างมาก

## Syntax

```excel
SUMMARIZE(&lt;table&gt;, &lt;groupBy_columnName&gt;[, &lt;groupBy_columnName&gt;]...)
```

**Variant**

```excel
SUMMARIZE(&lt;table&gt;, &lt;groupBy_columnName&gt;)
```

จัดกลุ่มตามคอลัมน์เดียว คืนค่า distinct values ของคอลัมน์นั้น (คล้าย VALUES แต่รองรับ related table columns โดยตรง)

**Variant**

```excel
SUMMARIZE(&lt;table&gt;, &lt;groupBy_columnName1&gt;, &lt;groupBy_columnName2&gt;)
```

จัดกลุ่มตามหลายคอลัมน์พร้อมกัน คืนค่า distinct combinations ของคอลัมน์ทั้งหมดที่มีอยู่จริงในข้อมูล (ไม่ใช่ Cartesian product)

**Variant**

```excel
SUMMARIZE(&lt;table&gt;, &lt;groupBy_columnName&gt;, "&lt;name&gt;", &lt;expression&gt;)
```

⚠️ Deprecated Pattern - เพิ่ม extension column โดยระบุชื่อและ expression (ไม่แนะนำ ควรใช้ ADDCOLUMNS แทน)

**Variant**

```excel
SUMMARIZE(&lt;table&gt;, ROLLUP(&lt;groupBy_columnName1&gt;, &lt;groupBy_columnName2&gt;))
```

สร้าง hierarchical subtotals และ grand total rows โดยอัตโนมัติ ใช้กับ ISSUBTOTAL เพื่อระบุ subtotal level (⚠️ ไม่ preserve data lineage)

## Arguments

| Name | Required | Type | Default | Description |
| --- | --- | --- | --- | --- |
| table | Yes | table |  | ตารางข้อมูลที่ต้องการจัดกลุ่มและสรุป สามารถเป็นชื่อตารางโดยตรง หรือ table expression จากฟังก์ชันอื่นเช่น FILTER (กรองก่อนจัดกลุ่ม), ALL (ดึงข้อมูลทั้งหมดโดยไม่คำนึงถึง filter context), หรือ CALCULATETABLE (ปรับเปลี่ยน filter context ก่อนจัดกลุ่ม) SUMMARIZE จะรักษา filter context ที่กระทบกับตารางนี้ไว้ตลอดการทำงาน |
| groupBy_columnName | No | column | ไม่มีการจัดกลุ่ม (คืนค่าตารางเดิม) | คอลัมน์ที่ต้องการใช้เป็นเกณฑ์หลักในการจัดกลุ่มข้อมูล ต้องระบุเป็นชื่อคอลัมน์แบบครบถ้วนในรูปแบบ Table[Column] และต้องเป็นคอลัมน์ที่มีอยู่จริง ไม่สามารถใช้นิพจน์คำนวณแทนได้ ข้อดีเด่นของ SUMMARIZE คือสามารถอ้างถึงคอลัมน์จาก related table ได้โดยตรงโดยไม่ต้องใช้ฟังก์ชัน RELATED เมื่อระบุหลายคอลัมน์พร้อมกัน ผลลัพธ์จะเป็น distinct combinations ของคอลัมน์ทั้งหมด สามารถใช้ฟังก์ชัน ROLLUP ครอบคอลัมน์เพื่อสร้าง hierarchical subtotals |
| name | No | text | ไม่มีคอลัมน์คำนวณเพิ่มเติม | ⚠️ Deprecated Parameter - ชื่อของคอลัมน์คำนวณเพิ่มเติม (extension column) ที่ต้องการสร้างในตารางผลลัพธ์ ต้องระบุเป็นข้อความภายใน double quotes และต้องมี expression parameter คู่กัน Microsoft และ SQLBI แนะนำอย่างเป็นทางการว่า parameter นี้ไม่ควรใช้แล้วเนื่องจากมีปัญหาด้าน performance และความยากในการควบคุม filter context แนวทางที่ดีกว่าคือใช้ ADDCOLUMNS function ครอบ SUMMARIZE จากภายนอกแทน |
| expression | No | scalar | ไม่มีนิพจน์คำนวณ | ⚠️ Deprecated Parameter - นิพจน์คำนวณของ DAX ที่คืนค่า scalar value สำหรับคำนวณค่าสรุปของแต่ละกลุ่ม expression นี้จะถูก evaluate ภายใน filter context ที่ SUMMARIZE สร้างขึ้นสำหรับแต่ละกลุ่มโดยอัตโนมัติ ซึ่งอาจทำให้เกิดผลลัพธ์ที่ไม่คาดหวังในบางกรณี ต้องมี name parameter คู่กัน Microsoft และ SQLBI แนะนำให้ใช้รูปแบบ ADDCOLUMNS(SUMMARIZE(...), "name", CALCULATE(expression)) แทนเพื่อควบคุม filter context ได้ชัดเจนและได้ performance ดีกว่า |

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

### สร้าง Virtual Table ใน Measure เพื่อ Intermediate Grouping

ใช้ SUMMARIZE สร้างตารางสรุปข้อมูลตามกลุ่มเพื่อเก็บไว้ใน VAR จากนั้นใช้ iterator functions (SUMX, AVERAGEX, COUNTX) คำนวณค่าสถิติต่างๆ จากกลุ่มข้อมูลนั้น เป็น use case หลักของ SUMMARIZE ในยุคปัจจุบัน

_เหมาะกับ:_ intermediate-grouping-with-iterators

### Distinct Multi-Column Combinations

ใช้ SUMMARIZE(table, col1, col2, col3) เพื่อดึง unique combinations ของหลายคอลัมน์พร้อมกันที่มีอยู่จริงในข้อมูล คล้ายการทำ Remove Duplicates หลายคอลัมน์พร้อมกัน เนื่องจาก VALUES และ DISTINCT ใช้ได้เฉพาะคอลัมน์เดียว

_เหมาะกับ:_ multi-column-distinct-values

### Cross-Table Grouping with Related Columns

SUMMARIZE สามารถอ้างถึงคอลัมน์จาก related table ได้โดยตรงโดยไม่ต้องใช้ RELATED เหมาะสำหรับจัดกลุ่มข้อมูลข้ามหลายตารางที่มี relationship กัน เช่น group Sales ตาม Products[Category] และ Customers[Region] พร้อมกัน

_เหมาะกับ:_ cross-table-related-grouping

### Hierarchical Reporting with ROLLUP Subtotals

ใช้ ROLLUP function เพื่อสร้างตารางที่มี subtotal rows สำหรับแต่ละระดับของ hierarchy (เช่น ยอดรวมตามปี ตาม quarter และ grand total) พร้อมใช้ ISSUBTOTAL ระบุว่า row ไหนเป็น subtotal level ไหน เหมาะสำหรับ hierarchical report

_เหมาะกับ:_ hierarchical-subtotals-reporting

## ตัวอย่าง

### 1. ตัวอย่างที่ 1: Basic Grouping - Single Column Distinct Values

```excel
// CALCULATED TABLE: สร้างตารางแสดง distinct categories
Unique Categories = 
SUMMARIZE(
    Sales,
    Products[Category]
)

// Context:
// - Sales table มี relationship กับ Products table (many-to-one)
// - Products[Category] มีค่า: Electronics, Furniture, Clothing (ซ้ำหลาย row)
// - SUMMARIZE group ตาม Category และคืนค่าเฉพาะ distinct values
```

**ผลลัพธ์:** `ตารางที่มี 1 คอลัมน์ (Category) และ 3 rows:
- Electronics
- Furniture
- Clothing`

SUMMARIZE จัดกลุ่มตาราง Sales ตามคอลัมน์ Category จาก related table (Products) โดยไม่ต้องใช้ RELATED function
.
ผลลัพธ์คือ distinct values ของ Category ทั้งหมด คล้ายกับใช้ VALUES(Products[Category]) หรือ DISTINCT(Products[Category]) แต่ SUMMARIZE มีข้อดีคือสามารถขยายเป็นหลายคอลัมน์ได้ในภายหลังและรองรับ related table columns โดยตรง

### 2. ตัวอย่างที่ 2: Multi-Column Grouping - Distinct Combinations

```excel
// CALCULATED TABLE: สร้างตารางแสดง Year-Category combinations ที่มีการขายจริง
Year Category Pairs = 
SUMMARIZE(
    Sales,
    'Date'[CalendarYear],
    Products[Category]
)

// Context:
// - Sales table มี relationship กับทั้ง Date และ Products tables
// - Date[CalendarYear]: 2022, 2023, 2024 (3 years)
// - Products[Category]: Electronics, Furniture, Clothing (3 categories)
// - Possible combinations: 3 × 3 = 9
// - แต่มีเพียง 7 combinations ที่มีการขายจริง
```

**ผลลัพธ์:** `ตารางที่มี 2 คอลัมน์ (CalendarYear, Category) และ 7 rows:
- 2022, Electronics
- 2022, Furniture
- 2023, Electronics
- 2023, Furniture
- 2023, Clothing
- 2024, Electronics
- 2024, Clothing

(ไม่มี 2022-Clothing และ 2024-Furniture เพราะไม่มีการขาย)`

SUMMARIZE สร้างตารางที่มี distinct combinations ของ Year และ Category ที่มีอยู่จริงในข้อมูล Sales
.
ไม่ใช่ Cartesian product ทั้งหมด (9 combinations) แต่เป็นเฉพาะ combinations ที่มีการขายเกิดขึ้นจริงเท่านั้น (7 combinations) ส่วนตัวผมใช้แบบนี้บ่อยเวลาต้องการรู้ว่ามี Category ไหนขายใน Year ไหนบ้าง 💡

### 3. ตัวอย่างที่ 3: Best Practice - SUMMARIZE + ADDCOLUMNS + CALCULATE

```excel
// MEASURE: คำนวณยอดขายเฉลี่ยต่อลูกค้า 1 คน
Average Sales Per Customer = 
VAR CustomerSales =
    ADDCOLUMNS(
        SUMMARIZE(
            Sales,
            Sales[CustomerID]
        ),
        "CustomerTotal", CALCULATE(SUM(Sales[Amount]))
    )
VAR AverageSales =
    AVERAGEX(
        CustomerSales,
        [CustomerTotal]
    )
RETURN
    AverageSales

// Context:
// - Sales table มี CustomerID และ Amount columns
// - ปัจจุบัน filter context แสดงข้อมูล 50 customers
// - แต่ละคนซื้อหลาย transactions (รวมกว่า 200 rows)
```

**ผลลัพธ์:** `ค่าเฉลี่ยยอดขายต่อลูกค้า 1 คน เช่น 12,450.00 บาท

(คำนวณจาก: รวมยอดขายของแต่ละคนก่อน จากนั้นหาค่าเฉลี่ยจาก 50 คน)`

นี่คือ best practice pattern ที่ Microsoft และ SQLBI แนะนำอย่างเป็นทางการ
.
ขั้นตอนการทำงาน: (1) ใช้ SUMMARIZE group ตาราง Sales ตาม CustomerID ได้ virtual table ที่มี 50 rows (2) ใช้ ADDCOLUMNS เพิ่มคอลัมน์ CustomerTotal โดย wrap SUM ด้วย CALCULATE เพื่อสร้าง filter context ที่ถูกต้อง (3) ใช้ AVERAGEX iterate ผ่าน CustomerSales table และหาค่าเฉลี่ยของ CustomerTotal column
.
เอาจริงๆ รูปแบบนี้ให้ performance ดีที่สุดและควบคุม filter context ได้ชัดเจนครับ ⚠️ ห้ามใส่ extension column ใน SUMMARIZE โดยตรง 😅

### 4. ตัวอย่างที่ 4: Multi-Level Analysis with Multiple Grouping Columns

```excel
// MEASURE: หา Region-Category combination ที่มียอดขายสูงสุด
Top Region Category Sales = 
VAR RegionCategorySales =
    ADDCOLUMNS(
        SUMMARIZE(
            Sales,
            Customers[Region],
            Products[Category]
        ),
        "Total", CALCULATE(SUM(Sales[Amount]))
    )
VAR TopCombination =
    TOPN(
        1,
        RegionCategorySales,
        [Total],
        DESC
    )
RETURN
    SUMX(TopCombination, [Total])

// Context:
// - Sales ↔ Customers (มี Region column: North, South, East, West)
// - Sales ↔ Products (มี Category column: Electronics, Furniture, Clothing)
// - มี data covering 4 regions × 3 categories = 12 possible combinations
// - แต่มี actual data เพียง 10 combinations
```

**ผลลัพธ์:** `ยอดขายสูงสุดของ Region-Category combination ใดๆ เช่น 2,850,000 บาท

(อาจเป็น North-Electronics หรือ South-Furniture ขึ้นอยู่กับข้อมูล)`

SUMMARIZE สร้าง virtual table ที่จัดกลุ่มตามทั้ง Region และ Category พร้อมกัน (multi-level grouping) ได้ 10 rows (เฉพาะ combinations ที่มีข้อมูล)
.
จากนั้น ADDCOLUMNS เพิ่มคอลัมน์ Total ที่คำนวณยอดขายของแต่ละกลุ่มโดยใช้ CALCULATE สร้าง filter context ที่ถูกต้อง TOPN เลือก row ที่มียอดขายสูงสุด 1 row ออกมา และ SUMX ดึงค่า Total จาก row นั้น ส่วนตัวผมใช้เทคนิคนี้บ่อยมากในการวิเคราะห์ข้อมูลหลายมิติครับ 😎

### 5. ตัวอย่างที่ 5: Advanced - ROLLUP for Hierarchical Subtotals

```excel
// CALCULATED TABLE: สร้าง hierarchical report พร้อม subtotals
Sales Hierarchy = 
ADDCOLUMNS(
    SUMMARIZE(
        Sales,
        ROLLUP(
            'Date'[CalendarYear],
            Products[Category]
        )
    ),
    "Total Sales", CALCULATE(SUM(Sales[Amount])),
    "Transaction Count", CALCULATE(COUNTROWS(Sales)),
    "Is Year Subtotal", ISSUBTOTAL('Date'[CalendarYear]),
    "Is Grand Total", 
        ISSUBTOTAL('Date'[CalendarYear]) 
        && ISSUBTOTAL(Products[Category])
)

// Context:
// - Sales table with Date and Products relationships
// - 2 years (2023, 2024) × 3 categories (Electronics, Furniture, Clothing)
// - ROLLUP creates subtotals at each hierarchy level
```

**ผลลัพธ์:** `ตารางที่มี 11 rows:

Detail rows (6):
- 2023, Electronics, 450000, 150, FALSE, FALSE
- 2023, Furniture, 320000, 110, FALSE, FALSE
- 2023, Clothing, 280000, 95, FALSE, FALSE
- 2024, Electronics, 580000, 175, FALSE, FALSE
- 2024, Furniture, 410000, 135, FALSE, FALSE
- 2024, Clothing, 350000, 120, FALSE, FALSE

Year subtotals (2):
- 2023, [blank], 1050000, 355, FALSE, FALSE
- 2024, [blank], 1340000, 430, FALSE, FALSE

Category subtotals (3):
- [blank], Electronics, 1030000, 325, TRUE, FALSE
- [blank], Furniture, 730000, 245, TRUE, FALSE
- [blank], Clothing, 630000, 215, TRUE, FALSE

Grand total (1):
- [blank], [blank], 2390000, 785, TRUE, TRUE`

ROLLUP function สร้าง subtotal rows ตาม hierarchy ที่กำหนด (Year → Category) โดยอัตโนมัติ
.
ใช้ ADDCOLUMNS เพื่อเพิ่มคอลัมน์คำนวณ (Total Sales และ Transaction Count) รวมทั้งคอลัมน์ flag สำหรับระบุว่า row นั้นเป็น subtotal level ไหน โดยใช้ ISSUBTOTAL function ตรวจสอบ
.
ที่ต้องระวังคือ ROLLUP ทำให้ SUMMARIZE ไม่ preserve data lineage ซึ่งอาจทำให้เกิด error ถ้านำคอลัมน์จาก ROLLUP ไปใช้ใน filter context ภายหลังครับ 😅

### 6. ตัวอย่างที่ 6: SUMMARIZE vs SUMMARIZECOLUMNS - When to Use What

```excel
// ❌ SUMMARIZE - Deprecated pattern (ไม่แนะนำ)
Sales by Category Wrong =
SUMMARIZE(
    Sales,
    Products[Category],
    "Total", SUM(Sales[Amount])  // Performance issue!
)

// ✅ SUMMARIZE + ADDCOLUMNS - Best for measures
Sales by Category in Measure =
VAR CategorySales =
    ADDCOLUMNS(
        SUMMARIZE(Sales, Products[Category]),
        "Total", CALCULATE(SUM(Sales[Amount]))
    )
RETURN
    COUNTROWS(CategorySales)  // นับจำนวน categories

// ✅ SUMMARIZECOLUMNS - Best for calculated tables
Sales by Category Table =
SUMMARIZECOLUMNS(
    Products[Category],
    'Date'[CalendarYear],
    FILTER(
        ALL('Date'[CalendarYear]),
        'Date'[CalendarYear] >= 2023
    ),
    "Total Sales", SUM(Sales[Amount]),
    "Avg Sales", AVERAGE(Sales[Amount])
)

// Context:
// - SUMMARIZE works in all contexts but needs ADDCOLUMNS for best practice
// - SUMMARIZECOLUMNS has better performance but limited contexts
```

**ผลลัพธ์:** `SUMMARIZE + ADDCOLUMNS (measure):
- Returns: 3 (จำนวน categories ที่มีการขาย)
- Works: ใน measure context ทุกประเภท
- Performance: ดี (ถ้าใช้ pattern ที่ถูกต้อง)

SUMMARIZECOLUMNS (table):
- Returns: ตารางที่มี Category, Year, Total Sales, Avg Sales
- Filter: เฉพาะปี 2023 ขึ้นไป
- Performance: ดีที่สุด ("very optimized query plan")
- Limitation: ใช้ไม่ได้ในบาง measure context`

ตัวอย่างนี้แสดงความแตกต่างและ use case ที่เหมาะสมของแต่ละฟังก์ชัน
.
(1) SUMMARIZE + ADDCOLUMNS เหมาะสำหรับสร้าง virtual table ใน measure เพื่อทำ intermediate calculations ทำงานได้ทุก context รองรับ row context transition และ complex filter context
.
(2) SUMMARIZECOLUMNS ออกแบบมาสำหรับ calculated table และ DAX query scenarios มี performance สูงสุดเนื่องจาก optimized query plan สามารถระบุ filter arguments และเรียกใช้ measure โดยตรง
.
เอาจริงๆ แนวทาง: ใช้ SUMMARIZECOLUMNS สำหรับ calculated table เพื่อ performance สูงสุด ใช้ SUMMARIZE + ADDCOLUMNS สำหรับ measure ที่ต้องการ virtual table 💡

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

⚠️ คำเตือนเกี่ยวกับรูปแบบการใช้งานที่ไม่แนะนำอีกต่อไป: ทางองค์กร Microsoft และทีมผู้เชี่ยวชาญจาก SQLBI ได้ออกคำแนะนำอย่างเป็นทางการว่า SUMMARIZE ไม่ควรใช้สำหรับเพิ่มคอลัมน์คำนวณเพิ่มเติมโดยตรงภายในฟังก์ชันแล้ว แม้ว่าจะมี syntax รองรับการใช้พารามิเตอร์ name และ expression เพื่อเพิ่ม extension columns ได้ในคำสั่งเดียว แต่รูปแบบนี้มีปัญหาทั้งด้านประสิทธิภาพและความยากในการควบคุม filter context ควรใช้ฟังก์ชัน ADDCOLUMNS ครอบ SUMMARIZE จากภายนอกแทนเสมอเพื่อให้ได้ performance ที่ดีที่สุดและควบคุม filter context ได้ชัดเจน

✅ รูปแบบที่แนะนำสำหรับการใช้งาน (BEST PRACTICE PATTERN):
เมื่อต้องการสร้างตารางสรุปพร้อมคอลัมน์คำนวณเพิ่มเติม ควรใช้รูปแบบนี้เสมอ:
VAR GroupedTable = ADDCOLUMNS(SUMMARIZE(table, columns), "name", CALCULATE(expression))

รูปแบบดังกล่าวจะให้ประสิทธิภาพในการทำงานที่ดีที่สุดและทำให้สามารถควบคุม filter context ได้อย่างชัดเจนและแม่นยำ การใช้ CALCULATE ครอบ expression ภายใน ADDCOLUMNS เป็นสิ่งจำเป็นอย่างยิ่งเพื่อให้ filter context ทำงานถูกต้องตามที่คาดหวัง

🔄 ทางเลือกสมัยใหม่ที่แนะนำ (MODERN ALTERNATIVES):
สำหรับการสร้าง calculated table หรือการเขียน DAX query ให้ใช้ SUMMARIZECOLUMNS แทน SUMMARIZE เนื่องจากมีประสิทธิภาพสูงสุด Microsoft ระบุชัดเจนว่า SUMMARIZECOLUMNS สร้าง query plan ที่เพิ่มประสิทธิภาพมากที่สุดและต้องการ storage engine query เพียงครั้งเดียวเท่านั้น สำหรับกรณีที่ไม่ต้องการให้ระบบขยาย table relationship โดยอัตโนมัติให้ใช้ GROUPBY แทน และสำหรับการสร้าง virtual table ภายใน measure ที่มี context ซับซ้อนให้ใช้ SUMMARIZE ร่วมกับ ADDCOLUMNS ตามรูปแบบที่แนะนำ

📊 พฤติกรรมของ CONTEXT ที่ต้องเข้าใจ (CONTEXT BEHAVIOR):
เมื่อใช้งาน SUMMARIZE ใน filter context เช่นภายใน measure ฟังก์ชันจะรักษา filter context ที่กระทบกับตารางไว้ตลอดการทำงานและคืนค่าเฉพาะข้อมูลที่ผ่าน filter เท่านั้น ส่วนเมื่อใช้งานใน row context เช่นภายใน calculated column ฟังก์ชันจะทำ context transition โดยอัตโนมัติโดยการแปลง row context เป็น filter context สำหรับแต่ละแถว สำหรับ extension columns ที่ไม่แนะนำให้ใช้แล้วนั้น expression จะถูก evaluate ภายใน filter context ที่ SUMMARIZE สร้างขึ้นสำหรับแต่ละกลุ่มโดยอัตโนมัติซึ่งยากต่อการควบคุมและอาจให้ผลลัพธ์ที่ไม่คาดหวัง

⚠️ ข้อจำกัดของ ROLLUP ที่ต้องระวัง (ROLLUP LIMITATIONS):
การใช้ฟังก์ชัน ROLLUP เพื่อสร้าง hierarchical subtotals มีข้อจำกัดสำคัญที่ต้องทราบ ประการแรกคือ ROLLUP ทำให้ SUMMARIZE ไม่สามารถรักษา data lineage ของคอลัมน์ที่ใช้ใน ROLLUP ได้ ซึ่งอาจทำให้เกิด error ในภายหลังถ้านำคอลัมน์เหล่านั้นไปใช้ใน filter context ประการที่สองคือ ROLLUP สร้างแถวเพิ่มเติมจำนวนมากซึ่งอาจทำให้ช้าในกรณีที่มี hierarchy หลายระดับ สำหรับกรณีที่ต้องการป้องกัน partial subtotals สามารถใช้ ROLLUPGROUP ครอบคอลัมน์ที่ต้องการจัดกลุ่มเข้าด้วยกันได้ ซึ่งจะทำให้แสดงเฉพาะ grand total สำหรับกลุ่มนั้นโดยไม่แสดง subtotal ระหว่างทาง

🔍 ความเข้ากันได้และข้อจำกัดของระบบ (COMPATIBILITY):
SUMMARIZE สามารถใช้งานได้ในหลากหลายบริบทรวมถึง Calculated Columns, Calculated Tables, Measures และ Visual Calculations อย่างไรก็ตามมีข้อจำกัดสำคัญคือไม่สามารถใช้งานได้ใน DirectQuery mode เมื่ออยู่ภายใน Calculated Columns หรือ Row-Level Security rules ซึ่งเป็นข้อจำกัดที่เกิดจากลักษณะการทำงานของ DirectQuery ที่ต้องแปลง DAX expression เป็น SQL query ฟังก์ชันนี้มีมาตั้งแต่ DAX เวอร์ชันแรกในปี 2010 แต่แนวทางปฏิบัติที่ดีที่สุดได้เปลี่ยนแปลงไปตามการเกิดของฟังก์ชันทางเลือกสมัยใหม่อย่าง SUMMARIZECOLUMNS และ GROUPBY

🎯 การรองรับตารางที่มีความสัมพันธ์กัน (RELATED TABLE SUPPORT):
ข้อได้เปรียบสำคัญของ SUMMARIZE คือความสามารถในการอ้างถึงคอลัมน์จาก related table ได้โดยตรงโดยไม่จำเป็นต้องใช้ฟังก์ชัน RELATED ซึ่งทำให้ง่ายต่อการสร้าง multi-table grouping ที่จัดกลุ่มข้อมูลข้ามหลายตารางพร้อมกัน อย่างไรก็ตามการขยาย relationship โดยอัตโนมัตินี้อาจมี performance overhead ในบางกรณี ดังนั้นถ้าไม่ต้องการให้มีการขยาย relationship และต้องการประสิทธิภาพสูงสุดควรพิจารณาใช้ GROUPBY แทนซึ่งจะทำงานเฉพาะกับตารางเดียวโดยไม่ขยาย relationship

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

**Q: ทำไมไม่แนะนำให้ใส่คอลัมน์คำนวณเพิ่มเติมใน SUMMARIZE โดยตรง?**

Microsoft และ SQLBI แนะนำอย่างเป็นทางการให้หลีกเลี่ยงการใช้พารามิเตอร์ name และ expression ใน SUMMARIZE เพื่อเพิ่มคอลัมน์คำนวณโดยตรง
.
มีเหตุผลสำคัญสามประการ: (1) Performance Issues - ฟังก์ชัน ADDCOLUMNS ให้ประสิทธิภาพที่ดีกว่าเพราะตัว DAX engine สามารถเพิ่มประสิทธิภาพ query plan ได้ดีกว่า (2) Filter Context Control - คอลัมน์คำนวณที่ถูกเพิ่มเข้าไปใน SUMMARIZE โดยตรงจะถูก evaluate ภายใน filter context ที่ SUMMARIZE สร้างขึ้นโดยอัตโนมัติ ซึ่งยากต่อการควบคุมและอาจให้ผลลัพธ์ที่ไม่คาดหวัง (3) Code Readability - การแยกส่วนของ grouping logic และ calculation logic ออกจากกันอย่างชัดเจนทำให้โค้ดอ่านง่ายและบำรุงรักษาได้สะดวกกว่า
.
ส่วนตัวผมแนะนำให้ใช้รูปแบบ ADDCOLUMNS(SUMMARIZE(table, columns), "name", CALCULATE(expression)) เสมอครับ 😎

**Q: SUMMARIZE ต่างจาก SUMMARIZECOLUMNS อย่างไร และควรใช้ตัวไหน?**

SUMMARIZECOLUMNS เป็นฟังก์ชันรุ่นใหม่ที่ Microsoft ออกแบบมาเพื่อแก้ไขข้อจำกัดของ SUMMARIZE มี performance ดีกว่าอย่างมาก ("produces a very optimized query plan requiring just one storage engine query") รองรับ filter arguments และ measure โดยตรง และมี syntax ที่ยืดหยุ่นกว่า
.
อย่างไรก็ตามมีข้อจำกัดสำคัญคือใช้ไม่ได้ในบาง measure context ที่มี complex context transition SUMMARIZE ยังคงจำเป็นสำหรับการสร้าง virtual table ใน measure เพื่อทำ intermediate calculations
.
แนวทางการเลือกใช้: (1) ใช้ SUMMARIZECOLUMNS สำหรับ calculated table หรือ DAX query ที่ต้องการ performance สูงสุด (2) ใช้ SUMMARIZE + ADDCOLUMNS สำหรับ measure ที่ต้องการ group data ก่อนนำไป iterate ด้วย SUMX, AVERAGEX เป็นต้น (3) ใช้ GROUPBY เมื่อต้องการใช้ CURRENTGROUP function

**Q: SUMMARIZE ต่างจาก VALUES และ DISTINCT อย่างไร?**

ความแตกต่างหลัก 3 ประการ: (1) จำนวนคอลัมน์ - VALUES และ DISTINCT ใช้ได้เฉพาะกับคอลัมน์เดียว ส่วน SUMMARIZE สามารถจัดกลุ่มหลายคอลัมน์พร้อมกันเพื่อหา distinct combinations (2) Blank Row - VALUES จะเพิ่ม blank row ถ้ามี filter ที่ทำให้เกิด blank (เช่น relationship ที่ไม่ match) ส่วน DISTINCT และ SUMMARIZE ไม่เพิ่ม blank row อัตโนมัติ (3) Related Tables - SUMMARIZE สามารถอ้างถึงคอลัมน์จาก related table ได้โดยตรงโดยไม่ต้องใช้ RELATED function ส่วน VALUES และ DISTINCT ต้องใช้กับคอลัมน์ที่อยู่ในตารางที่ระบุเท่านั้น
.
แนวทางการเลือกใช้: ถ้าต้องการ distinct values คอลัมน์เดียว ใช้ VALUES (หรือ DISTINCT ถ้าไม่ต้องการ blank row) ถ้าต้องการ multi-column combinations หรือ cross-table grouping ใช้ SUMMARIZE

**Q: ROLLUP ใน SUMMARIZE ทำงานอย่างไร และมีข้อจำกัดอะไร?**

ROLLUP function สร้าง subtotal rows ตาม hierarchy ที่กำหนดโดยอัตโนมัติ เช่น ROLLUP(Year, Quarter, Month) จะสร้าง: (1) Detail rows สำหรับทุก Year-Quarter-Month combination (2) Subtotal rows สำหรับแต่ละ Year-Quarter (3) Subtotal rows สำหรับแต่ละ Year (4) Grand total row ใช้คู่กับ ISSUBTOTAL function เพื่อระบุว่า row ไหนเป็น subtotal level ไหน
.
ข้อจำกัดสำคัญ 2 ประการ: (1) Data Lineage - ROLLUP ทำให้ SUMMARIZE ไม่ preserve data lineage ของคอลัมน์ที่ใช้ใน ROLLUP ซึ่งอาจทำให้เกิด error ถ้านำคอลัมน์เหล่านั้นไปใช้ใน filter context ภายหลัง (2) Performance - ROLLUP สร้าง rows เพิ่มเติมมากทำให้ช้าในกรณีที่มี hierarchy หลายระดับ
.
ส่วนตัวผม สำหรับ reporting ที่ซับซ้อน แนะนำให้ใช้ SUMMARIZECOLUMNS แทนครับ 😅

**Q: SUMMARIZE ทำงานอย่างไรกับ Filter Context และ Row Context?**

SUMMARIZE มี context behavior ที่สำคัญต้องเข้าใจ: (1) ใน Filter Context (เช่น measure) - SUMMARIZE รักษา filter context ที่กระทบกับตารางที่ระบุไว้ตลอดการทำงาน จะคืนค่าตารางที่มีเฉพาะข้อมูลที่ผ่าน filter เท่านั้น (2) ใน Row Context (เช่น calculated column) - SUMMARIZE ทำ context transition โดยอัตโนมัติ แปลง row context เป็น filter context สำหรับแต่ละ row (3) Extension Columns - ถ้าใช้ name/expression parameters (ไม่แนะนำ) expression จะถูก evaluate ใน filter context ที่ SUMMARIZE สร้างขึ้นสำหรับแต่ละกลุ่ม ซึ่งอาจให้ผลลัพธ์ที่ไม่คาดหวังถ้าไม่ระวัง
.
ที่เจ๋งคือนี่คือเหตุผลที่ต้องใช้ CALCULATE ครอบ expression ใน ADDCOLUMNS เพื่อควบคุม filter context ให้ชัดเจนครับ Best practice: ใช้ VAR เก็บ SUMMARIZE result ไว้ก่อน จากนั้นใช้ ADDCOLUMNS พร้อม CALCULATE เพื่อเพิ่มคอลัมน์คำนวณ รูปแบบนี้ควบคุม context ได้ชัดเจนและ debug ง่าย 💡

**Q: เมื่อไหร่ควรใช้ SUMMARIZE และเมื่อไหร่ควรใช้ GROUPBY?**

SUMMARIZE และ GROUPBY มีความคล้ายคลึงกันในการจัดกลุ่มข้อมูล แต่มีความแตกต่างสำคัญ: (1) Table Expansion - SUMMARIZE ขยาย relationship โดยอัตโนมัติและสามารถอ้างถึงคอลัมน์จาก related table ได้โดยตรง ส่วน GROUPBY ไม่ขยาย relationship (ต้องอยู่ในตารางเดียวกัน) (2) Aggregation Pattern - GROUPBY รองรับ aggregation โดยตรงภายในฟังก์ชัน และมีฟังก์ชัน CURRENTGROUP() สำหรับเข้าถึงข้อมูลในแต่ละกลุ่ม ส่วน SUMMARIZE ต้องใช้คู่กับ ADDCOLUMNS (3) Performance - GROUPBY มี performance ดีกว่าในบางกรณีเนื่องจากไม่ต้องขยาย relationship
.
แนวทางการเลือกใช้: ใช้ SUMMARIZE เมื่อต้องการ group ข้าม related tables หรือต้องการ syntax ที่ง่ายกว่า ใช้ GROUPBY เมื่อต้องการ performance สูงสุดในตารางเดียวหรือต้องการใช้ CURRENTGROUP function

**Q: SUMMARIZE รองรับการใช้งานใน DirectQuery mode หรือไม่?**

SUMMARIZE ไม่รองรับใน DirectQuery mode เมื่อใช้ใน calculated columns หรือ Row-Level Security (RLS) rules ตามที่ Microsoft ระบุอย่างชัดเจน
.
อย่างไรก็ตาม SUMMARIZE สามารถใช้งานได้ใน DirectQuery mode เมื่ออยู่ใน measures และ calculated tables ข้อจำกัดนี้เกิดจากลักษณะการทำงานของ DirectQuery ที่ต้องแปลง DAX expression เป็น SQL query ซึ่ง SUMMARIZE ที่มี row context (เช่นใน calculated column) และ RLS rules ไม่สามารถแปลงได้อย่างมีประสิทธิภาพ
.
ถ้าต้องการใช้ grouping ใน DirectQuery mode สำหรับ calculated columns แนะนำให้ทำการ group ที่ source database แทนหรือใช้ Import mode สำหรับตารางที่มี calculated columns ที่ใช้ SUMMARIZE

## ฟังก์ชันที่เกี่ยวข้อง

- [SUMMARIZECOLUMNS – สร้างตารางสรุปแบบ Dynamic Query](https://www.thepexcel.com/functions/dax/table-manipulation/summarizecolumns-dax/)
- [ADDCOLUMNS – เพิ่มคอลัมน์คำนวณให้ตาราง](https://www.thepexcel.com/functions/dax/table-manipulation/addcolumns-dax/)
- [GROUPBY – จัดกลุ่มและคำนวณแบบละเอียด](https://www.thepexcel.com/functions/dax/table-manipulation/groupby-dax/)
- [CALCULATE – ฟังก์ชันหลักของ DAX ที่ควบคุม Filter Context](https://www.thepexcel.com/functions/dax/filter/calculate-dax/)
- [CALCULATETABLE – Evaluate Table Expression ใน Modified Filter Context](https://www.thepexcel.com/functions/dax/filter/calculatetable-dax/)
- [SUMX – Iterator Function สำหรับคำนวณผลรวมแบบ Row-by-Row ใน DAX](https://www.thepexcel.com/functions/dax/aggregation/sumx-dax/)
- [AVERAGEX – หาค่าเฉลี่ยจากนิพจน์ที่คำนวณในแต่ละแถว](https://www.thepexcel.com/functions/dax/aggregation/averagex-dax/)
- [COUNTX – นับจำนวนแถวจากนิพจน์ที่คำนวณต่อแถว](https://www.thepexcel.com/functions/dax/aggregation/countx-dax/)
- [MAXX – หาค่ามากที่สุดจากนิพจน์แบบไล่ทีละแถว](https://www.thepexcel.com/functions/dax/aggregation/maxx-dax/)
- [FILTER – กรองตารางด้วยเงื่อนไขที่ซับซ้อน (Iterator Function)](https://www.thepexcel.com/functions/dax/filter/filter-dax/)
- [ALL – ลบ Filter หรือคืนค่าทุกแถว](https://www.thepexcel.com/functions/dax/filter/all-dax/)
- [RELATED – ดึงค่าจากตารางที่มีความสัมพันธ์ (Many → One)](https://www.thepexcel.com/functions/dax/relationship/related-dax/)
- [DISTINCT – ดึงรายการที่ไม่ซ้ำ (Unique Values) พร้อมหลีกหนีค่า Blank Row](https://www.thepexcel.com/functions/dax/table-manipulation/distinct-dax/)
- [ROLLUP – สร้างแถว Subtotal ในตาราง SUMMARIZE](https://www.thepexcel.com/functions/dax/table-manipulation/rollup-dax/)
- [ROLLUPGROUP – จัดกลุ่มคอลัมน์เพื่อลดจำนวน subtotal ใน roll-up](https://www.thepexcel.com/functions/dax/table-manipulation/rollupgroup-dax/)
- issubtotal-dax
- [TOPN – คืนตาราง Top N ตามนิพจน์การเรียงลำดับ](https://www.thepexcel.com/functions/dax/table-manipulation/topn-dax/)
- [COUNTROWS – นับจำนวนแถวในตารางและเทบิลเสมือน](https://www.thepexcel.com/functions/dax/aggregation/countrows-dax/)
- [CURRENTGROUP – อ้างอิงตารางย่อยของกลุ่มใน GROUPBY](https://www.thepexcel.com/functions/dax/table-manipulation/currentgroup-dax/)
- [QUARTER – ฟังก์ชันแยกไตรมาสจากวันที่](https://www.thepexcel.com/functions/dax/date-and-time/quarter-dax/)

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

- [Microsoft Learn: SUMMARIZE function (DAX) - Official Documentation](https://learn.microsoft.com/en-us/dax/summarize-function-dax) _(documentation)_
- [DAX.guide: SUMMARIZE - Comprehensive Technical Reference](https://dax.guide/summarize/) _(documentation)_
- [SQLBI: Best practices using SUMMARIZE and ADDCOLUMNS](https://www.sqlbi.com/articles/best-practices-using-summarize-and-addcolumns/) _(guide)_
- [SQLBI: Introducing SUMMARIZECOLUMNS](https://www.sqlbi.com/articles/introducing-summarizecolumns/) _(guide)_
- [Microsoft Learn: SUMMARIZECOLUMNS function (DAX) - Modern Alternative](https://learn.microsoft.com/en-us/dax/summarizecolumns-function-dax) _(documentation)_
- [Microsoft Learn: GROUPBY function (DAX) - Performance Alternative](https://learn.microsoft.com/en-us/dax/groupby-function-dax) _(documentation)_
- [Microsoft Learn: ADDCOLUMNS function (DAX) - Best Practice Partner](https://learn.microsoft.com/en-us/dax/addcolumns-function-dax) _(documentation)_

---

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