---
title: Table.ExpandTableColumn – แตกข้อมูลจากคอลัมน์ตารางที่ซ้อนกัน
url: https://www.thepexcel.com/functions/power-query/table-functions/table-expandtablecolumn/
type: function-explainer
program: Power Query
syntax: "Table.ExpandTableColumn(table as table, column as text, columnNames as list, optional newColumnNames as nullable list) as table"
date: 2025-12-18
scores:
  popularity: 9
  difficulty: 4
  usefulness: 9
---

# Table.ExpandTableColumn – แตกข้อมูลจากคอลัมน์ตารางที่ซ้อนกัน

> แตกข้อมูลจากคอลัมน์ตารางซ้อนให้เป็นคอลัมน์และแถวปกติ

## คำอธิบาย

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

## Syntax

```excel
Table.ExpandTableColumn(table as table, column as text, columnNames as list, optional newColumnNames as nullable list) as table
```

**Variant**

```excel
Table.ExpandTableColumn(table, column, columnNames)
```

รูปแบบพื้นฐาน ใช้ชื่อคอลัมน์เดิมจากตารางซ้อน

**Variant**

```excel
Table.ExpandTableColumn(table, column, columnNames, newColumnNames)
```

รูปแบบเต็ม ระบุชื่อคอลัมน์ใหม่เพื่อหลีกเลี่ยงชื่อซ้ำ

## Arguments

| Name | Required | Type | Default | Description |
| --- | --- | --- | --- | --- |
| table | Yes | table |  | ตารางต้นทางที่มีคอลัมน์ซึ่งเก็บค่าเป็น table (nested table column) |
| column | Yes | text |  | ชื่อคอลัมน์ที่ต้องการแตกข้อมูล ซึ่งคอลัมน์นี้ต้องมีค่าเป็น table |
| columnNames | Yes | list |  | list ของชื่อคอลัมน์ในตารางซ้อนที่ต้องการดึงออกมาแสดง เช่น {"Name", "Price", "Quantity"} |
| newColumnNames | No | nullable list | null | list ของชื่อคอลัมน์ใหม่ที่จะใช้แทนชื่อเดิม เพื่อป้องกันปัญหาชื่อคอลัมน์ซ้ำกับตารางหลัก แนะนำให้ระบุเสมอเมื่อมีโอกาสชื่อซ้ำ |

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

### ขยายผลลัพธ์จาก Table.NestedJoin

หลังจากใช้ Table.NestedJoin เพื่อ join ตารางสองตารางเข้าด้วยกัน ผลลัพธ์จะมีคอลัมน์ที่เก็บตารางที่ join มา จำเป็นต้องใช้ Table.ExpandTableColumn เพื่อดึงคอลัมน์จากตารางที่ join มาแสดงในตารางหลัก

_เหมาะกับ:_ data-transformation

### แตกข้อมูลหลังการจัดกลุ่ม (Table.Group)

เมื่อใช้ Table.Group เพื่อจัดกลุ่มข้อมูลโดยไม่ใช้ aggregation function ผลลัพธ์จะได้ตารางซ้อนที่เก็บแถวทั้งหมดในแต่ละกลุ่ม ต้องใช้ Table.ExpandTableColumn เพื่อแตกกลับมาเป็นแถวปกติ

_เหมาะกับ:_ data-transformation

### ประมวลผลข้อมูล hierarchical จาก API หรือ JSON

ข้อมูลจาก Web API หรือไฟล์ JSON มักมีโครงสร้างแบบ nested tables (เช่น orders ที่มี order_items ซ้อนอยู่) ต้องใช้ Table.ExpandTableColumn เพื่อ flatten ข้อมูลให้อยู่ในรูป relational table

_เหมาะกับ:_ web-data

### แตกข้อมูลจากฐานข้อมูลที่มีความสัมพันธ์

บาง database connector คืนผลลัพธ์แบบ nested structure เช่น query ที่มี subquery หรือข้อมูลจากหลาย table ต้องใช้ Table.ExpandTableColumn เพื่อแปลงเป็น flat table

_เหมาะกับ:_ database

## ตัวอย่าง

### 1. ตัวอย่างที่ 1: การแตกคอลัมน์ตารางพื้นฐาน

```excel
let
    // สร้างตารางต้นทางที่มีคอลัมน์ ProductID และคอลัมน์ Details ที่เป็น table
    Source = Table.FromRecords({
        [
            ProductID = 1,
            Details = Table.FromRecords({
                [Color = "Red", Size = "M"],
                [Color = "Blue", Size = "L"]
            })
        ],
        [
            ProductID = 2,
            Details = Table.FromRecords({
                [Color = "Green", Size = "S"]
            })
        ]
    }),
    
    // แตกคอลัมน์ Details ออกมาเป็นคอลัมน์ Color และ Size
    Expanded = Table.ExpandTableColumn(
        Source,
        "Details",
        {"Color", "Size"}
    )
in
    Expanded
```

**ผลลัพธ์:** `Table ที่มี 3 แถว:
• ProductID=1, Color="Red", Size="M"
• ProductID=1, Color="Blue", Size="L"
• ProductID=2, Color="Green", Size="S"

คอลัมน์ Details ถูกแทนที่ด้วย Color และ Size`

นี่คือตัวอย่างพื้นฐานของการแตก nested table ครับ
.
สังเกตว่า ProductID=1 มี Details 2 แถว จึงกลายเป็น 2 แถวในผลลัพธ์ ส่วน ProductID=2 มี Details 1 แถว จึงได้ 1 แถว
.
คอลัมน์ ProductID ถูก "ทำซ้ำ" ให้ตรงกับจำนวนแถวใน nested table แต่ละแถว นี่คือ concept สำคัญของ ExpandTableColumn เลยครับ 💡

### 2. ตัวอย่างที่ 2: ใช้ newColumnNames เพื่อหลีกเลี่ยงชื่อซ้ำ

```excel
let
    // สร้างตารางที่มีคอลัมน์ OrderID, Amount และ Items (table) ที่มีคอลัมน์ Amount ซ้ำชื่อ
    Source = Table.FromRecords({
        [
            OrderID = 100,
            Amount = 5000,
            Items = Table.FromRecords({
                [Product = "Laptop", Amount = 2000, Qty = 2],
                [Product = "Mouse", Amount = 500, Qty = 2]
            })
        ],
        [
            OrderID = 101,
            Amount = 1500,
            Items = Table.FromRecords({
                [Product = "Keyboard", Amount = 1500, Qty = 1]
            })
        ]
    }),
    
    // แตกคอลัมน์ Items และเปลี่ยนชื่อ Amount เป็น ItemAmount เพื่อป้องกันชื่อซ้ำ
    Expanded = Table.ExpandTableColumn(
        Source,
        "Items",
        {"Product", "Amount", "Qty"},
        {"ProductName", "ItemAmount", "Quantity"}
    )
in
    Expanded
```

**ผลลัพธ์:** `Table ที่มี 3 แถว:
• OrderID=100, Amount=5000, ProductName="Laptop", ItemAmount=2000, Quantity=2
• OrderID=100, Amount=5000, ProductName="Mouse", ItemAmount=500, Quantity=2
• OrderID=101, Amount=1500, ProductName="Keyboard", ItemAmount=1500, Quantity=1

ไม่มีปัญหาชื่อคอลัมน์ซ้ำระหว่าง Amount (order) และ ItemAmount (item)`

ตัวอย่างนี้แสดงการใช้ argument ที่ 4 (newColumnNames) ซึ่งสำคัญมากครับ 💡
.
สังเกตว่าตารางหลักมีคอลัมน์ Amount (ยอดรวมของ order) และตารางซ้อนก็มี Amount (ราคาสินค้าแต่ละชิ้น) ถ้าไม่เปลี่ยนชื่อจะเกิด error ชื่อซ้ำทันที 😅
.
เลยต้องระบุ newColumnNames เพื่อเปลี่ยนชื่อให้ชัดเจน เช่น Amount → ItemAmount และ Product → ProductName
.
ส่วนตัวผมแนะนำให้ระบุ newColumnNames เสมอ แม้ชื่อจะไม่ซ้ำก็ตาม เพราะทำให้โค้ดอ่านง่ายและป้องกันปัญหาในอนาคต

### 3. ตัวอย่างที่ 3: ใช้ร่วมกับ Table.NestedJoin (ขยายข้อมูลจาก join)

```excel
let
    // ตารางลูกค้า
    Customers = Table.FromRecords({
        [CustomerID = 1, CustomerName = "Alice"],
        [CustomerID = 2, CustomerName = "Bob"]
    }),
    
    // ตารางคำสั่งซื้อ
    Orders = Table.FromRecords({
        [OrderID = 101, CustomerID = 1, OrderDate = #date(2024, 1, 15), Total = 2500],
        [OrderID = 102, CustomerID = 1, OrderDate = #date(2024, 2, 10), Total = 1200],
        [OrderID = 103, CustomerID = 2, OrderDate = #date(2024, 1, 20), Total = 3000]
    }),
    
    // Join ตารางโดยเก็บผลลัพธ์ไว้ใน nested table
    Joined = Table.NestedJoin(
        Customers,
        {"CustomerID"},
        Orders,
        {"CustomerID"},
        "CustomerOrders",
        JoinKind.LeftOuter
    ),
    
    // แตกคอลัมน์ CustomerOrders เพื่อดึงข้อมูล OrderDate และ Total
    Expanded = Table.ExpandTableColumn(
        Joined,
        "CustomerOrders",
        {"OrderID", "OrderDate", "Total"},
        {"OrderID", "OrderDate", "OrderTotal"}
    )
in
    Expanded
```

**ผลลัพธ์:** `Table ที่มี 3 แถว:
• CustomerID=1, CustomerName="Alice", OrderID=101, OrderDate=2024-01-15, OrderTotal=2500
• CustomerID=1, CustomerName="Alice", OrderID=102, OrderDate=2024-02-10, OrderTotal=1200
• CustomerID=2, CustomerName="Bob", OrderID=103, OrderDate=2024-01-20, OrderTotal=3000

ข้อมูลลูกค้าถูกทำซ้ำสำหรับแต่ละ order`

นี่คือ use case ที่เจอบ่อยที่สุดเลยครับ 😎
.
เราใช้ Table.NestedJoin เพื่อ join ตารางแบบ one-to-many (1 ลูกค้ามีหลาย orders) โดยเก็บตารางย่อยไว้ในคอลัมน์ CustomerOrders ก่อน
.
จากนั้นใช้ Table.ExpandTableColumn เพื่อแตกคอลัมน์ CustomerOrders ออกมา ผลลัพธ์คือแต่ละแถวของลูกค้าจะถูก "ทำซ้ำ" ตามจำนวน orders ที่มี
.
ส่วนตัวผมชอบ pattern นี้มากกว่า Table.Join ตรงๆ เพราะควบคุม join behavior ได้ละเอียดกว่า และเห็นภาพข้อมูลชัดเจนกว่า

### 4. ตัวอย่างที่ 4: เลือกแตกเฉพาะบางคอลัมน์จากตารางซ้อน

```excel
let
    // สร้างตารางที่มีข้อมูลพนักงานและประวัติการทำงาน
    Source = Table.FromRecords({
        [
            EmployeeID = "E001",
            EmployeeName = "John Doe",
            Department = "Sales",
            WorkHistory = Table.FromRecords({
                [Company = "ABC Corp", Position = "Sales Rep", Years = 3, Salary = 50000, StartDate = #date(2019, 1, 1)],
                [Company = "XYZ Ltd", Position = "Sales Manager", Years = 2, Salary = 70000, StartDate = #date(2022, 6, 1)]
            })
        ],
        [
            EmployeeID = "E002",
            EmployeeName = "Jane Smith",
            Department = "IT",
            WorkHistory = Table.FromRecords({
                [Company = "Tech Inc", Position = "Developer", Years = 5, Salary = 80000, StartDate = #date(2018, 3, 15)]
            })
        ]
    }),
    
    // แตกเฉพาะคอลัมน์ Company, Position และ Years จาก WorkHistory (ไม่เอา Salary และ StartDate)
    Expanded = Table.ExpandTableColumn(
        Source,
        "WorkHistory",
        {"Company", "Position", "Years"},
        {"PreviousCompany", "PreviousPosition", "YearsWorked"}
    )
in
    Expanded
```

**ผลลัพธ์:** `Table ที่มี 3 แถว:
• EmployeeID="E001", EmployeeName="John Doe", Department="Sales", PreviousCompany="ABC Corp", PreviousPosition="Sales Rep", YearsWorked=3
• EmployeeID="E001", EmployeeName="John Doe", Department="Sales", PreviousCompany="XYZ Ltd", PreviousPosition="Sales Manager", YearsWorked=2
• EmployeeID="E002", EmployeeName="Jane Smith", Department="IT", PreviousCompany="Tech Inc", PreviousPosition="Developer", YearsWorked=5

คอลัมน์ Salary และ StartDate ไม่ถูกดึงออกมา`

ตัวอย่างนี้แสดงเทคนิคที่สำคัญมากครับ ไม่จำเป็นต้องแตกทุกคอลัมน์จากตารางซ้อน 💡
.
สังเกตว่าตาราง WorkHistory มี 5 คอลัมน์ แต่เราเลือกแตกแค่ 3 คอลัมน์ที่สนใจ (Company, Position, Years) ไม่เอา Salary และ StartDate
.
วิธีนี้ช่วยลดขนาดข้อมูล ทำให้ query เร็วขึ้น และตารางอ่านง่ายขึ้นด้วย
.
ส่วนตัวผมมักใช้เทคนิคนี้เพื่อเลือกเฉพาะข้อมูลที่จำเป็นจริงๆ และเปลี่ยนชื่อให้มีความหมายชัดเจน เช่น Company → PreviousCompany เพื่อให้รู้ว่านี่คือข้อมูลในอดีต

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

💡 **Tip จากประสบการณ์จริง:**
.
Table.ExpandTableColumn เป็นฟังก์ชันที่ผมใช้บ่อยมากใน Power Query โดยเฉพาะตอนทำงานกับข้อมูลจาก API หรือ JSON ที่มีโครงสร้างแบบ nested
.
**ข้อควรระวัง (เจอมาแล้ว 😅):**
.
1. **Data Explosion** - นี่คือปัญหาใหญ่ที่สุด! เมื่อแตกตารางซ้อน จำนวนแถวจะพุ่งขึ้นอย่างรวดเร็ว 100 แถว x 1,000 nested rows = 100,000 แถว ทำให้ query ช้ามากหรือ crash ได้ ส่วนตัวผมจะตรวจสอบด้วย Table.RowCount ก่อนเสมอครับ
.
2. **Column Name Conflicts** - ถ้าไม่ระบุ newColumnNames แล้วชื่อซ้ำ... จบเลย error ทันที 😭 ผมแนะนำให้ระบุ newColumnNames เสมอ แม้ชื่อจะไม่ซ้ำก็ตาม เพราะทำให้โค้ดอ่านง่ายและป้องกันปัญหาในอนาคต
.
3. **Empty Nested Tables** - ถ้าตารางซ้อนว่างเปล่า แถวนั้นจะหายไปจากผลลัพธ์ (เหมือน Inner Join) นี่เป็น gotcha ที่ต้องระวัง ถ้าต้องการรักษาแถวไว้ ต้องเช็คก่อน expand หรือใช้ conditional logic
.
4. **Performance** - การแตกตารางซ้อนที่มีข้อมูลเยอะใช้เวลานาน ผมแนะนำให้:
   • เลือกเฉพาะคอลัมน์ที่ต้องการใน columnNames
   • ใช้ Table.FirstN จำกัดแถวก่อน expand
   • กรองข้อมูลที่ไม่จำเป็นออกก่อน
.
**เทคนิคขั้นสูง (ลองดูครับ 😎):**
.
• **Chain with Table.TransformColumns** - ประมวลผลข้อมูลในตารางซ้อนก่อนแตก
  ```
  Table.TransformColumns(Source, {{"Details", each Table.SelectRows(_, [Amount] > 1000)}})
  ```
.
• **Limit rows before expand** - ป้องกัน data explosion
  ```
  Table.TransformColumns(Source, {{"Items", each Table.FirstN(_, 10)}})
  ```
.
• **Handle empty tables** - ใช้ try...otherwise
  ```
  try Table.ExpandTableColumn(...) otherwise Source
  ```
.
• **Conditional expand** - ตรวจสอบก่อน expand
  ```
  if Table.RowCount([NestedTable]) > 0 then [...] else null
  ```
.
ส่วนตัวผมมักใช้ร่วมกับ Table.NestedJoin เพื่อควบคุม join behavior ได้ละเอียดกว่า Table.Join ธรรมดาครับ

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

**Q: ถ้าไม่ระบุ newColumnNames จะเกิดอะไรขึ้น?**

ถ้าไม่ระบุ newColumnNames ฟังก์ชันจะใช้ชื่อเดิมจากคอลัมน์ในตารางซ้อน ซึ่งอาจทำให้เกิดปัญหาชื่อคอลัมน์ซ้ำกับตารางหลักและเกิด error ได้
.
ยกตัวอย่างเช่น ถ้าตารางหลักมีคอลัมน์ "Amount" และตารางซ้อนก็มี "Amount" พอแตกออกมาจะมีชื่อซ้ำกัน Power Query จะ error ทันที 😭
.
ส่วนตัวผมแนะนำให้ระบุ newColumnNames เสมอครับ แม้ว่าชื่อจะไม่ซ้ำก็ตาม เพราะทำให้โค้ดอ่านง่ายและป้องกันปัญหาในอนาคต

**Q: ถ้าตารางซ้อนเป็น empty table (ไม่มีแถว) จะเกิดอะไรขึ้น?**

ถ้าตารางซ้อนไม่มีแถว (empty table) แถวนั้นจะหายไปจากผลลัพธ์เลยครับ 😭
.
ทำงานเหมือน Inner Join นั่นเอง ยกตัวอย่าง ถ้าใช้ Table.NestedJoin แบบ LeftOuter แล้วบางแถวไม่มีข้อมูล join ได้ (nested table ว่างเปล่า) พอเรา expand ออกมา... แถวนั้นจะหายไป
.
นี่เป็นพฤติกรรมที่ต้องระวังมากครับ ถ้าต้องการรักษาแถวเอาไว้ ต้องตรวจสอบก่อน expand ด้วย Table.RowCount หรือใช้ conditional logic เพื่อจัดการ case นี้

**Q: ต่างจาก Table.ExpandRecordColumn อย่างไร?**

คำถามนี้เจอบ่อยมากครับ เพราะชื่อคล้ายกันมาก 😅
.
**Table.ExpandTableColumn** → แตก nested **table** ซึ่ง 1 แถวอาจกลายเป็นหลายแถว (one-to-many)
.
**Table.ExpandRecordColumn** → แตก **record** ซึ่ง 1 แถวยังคงเป็น 1 แถว (one-to-one) แค่เพิ่มคอลัมน์เข้ามา
.
ใช้ **ExpandTableColumn** เมื่อ: คอลัมน์เป็น table และต้องการ flatten ทุกแถว (เช่น 1 order มีหลาย items)
.
ใช้ **ExpandRecordColumn** เมื่อ: คอลัมน์เป็น record และต้องการดึง field ออกมา (เช่น address record ที่มี street, city, zip)

**Q: สามารถแตกหลายคอลัมน์ตารางพร้อมกันได้หรือไม่?**

ไม่ได้โดยตรงครับ Table.ExpandTableColumn แตกได้ทีละ 1 คอลัมน์เท่านั้น
.
ถ้ามีหลายคอลัมน์ที่เป็น table ต้องเรียกฟังก์ชันนี้หลายครั้งต่อเนื่องกัน แบบนี้:
.
```
ExpandTableColumn(
    ExpandTableColumn(Source, "Col1", ...),
    "Col2",
    ...
)
```
.
หรือใช้ step แยกกันใน Power Query Editor ซึ่งอ่านง่ายกว่า ส่วนตัวผมชอบแยก step เพราะ debug ง่ายกว่าครับ 😎

**Q: จะป้องกันตารางขยายใหญ่เกินไป (data explosion) ได้อย่างไร?**

นี่เป็นปัญหาใหญ่ที่เจอบ่อยมากครับ 😭 ตารางที่มี 100 แถว ถ้าแต่ละแถวมี nested table 1,000 แถว พอ expand ได้ 100,000 แถวเลย!
.
**วิธีป้องกัน:**
.
1. **ตรวจสอบก่อน expand** ด้วย Table.AddColumn:
```
Table.AddColumn(Source, "RowCount", each Table.RowCount([Details]))
```
.
2. **จำกัดจำนวนแถว** ก่อน expand:
```
Table.TransformColumns(Source, {{"Details", each Table.FirstN(_, 10)}})
```
.
3. **กรองข้อมูล** ที่ไม่จำเป็นออกก่อน:
```
Table.SelectRows(Source, each Table.RowCount([Details])

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

- [Table.NestedJoin – รวมตารางพร้อมสร้างคอลัมน์ตารางย่อย](https://www.thepexcel.com/functions/power-query/table-functions/table-nestedjoin/)
- [Table.ExpandRecordColumn – ขยายคอลัมน์ที่เป็น Record ให้เป็นหลายคอลัมน์](https://www.thepexcel.com/?post_type=function-explainer&p=37949)
- [Table.ExpandListColumn – ขยาย List เป็นหลายแถว](https://www.thepexcel.com/functions/power-query/table-functions/table-expandlistcolumn/)
- [Table.Group – จัดกลุ่มและสรุปผลข้อมูล (Group By)](https://www.thepexcel.com/functions/power-query/table-functions/table-group/)
- [Table.Join – รวมตารางแบบ SQL Join](https://www.thepexcel.com/functions/power-query/table-functions/table-join/)

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

- [Microsoft Learn: Table.ExpandTableColumn function](https://learn.microsoft.com/en-us/powerquery-m/table-expandtablecolumn) _(documentation)_
- [Microsoft Learn: Table.NestedJoin function](https://learn.microsoft.com/en-us/powerquery-m/table-nestedjoin) _(documentation)_
- [PowerQuery.how: Table.ExpandTableColumn](https://powerquery.how/table-expandtablecolumn/) _(guide)_

---

_Source: [https://www.thepexcel.com/functions/power-query/table-functions/table-expandtablecolumn/](https://www.thepexcel.com/functions/power-query/table-functions/table-expandtablecolumn/)_
