---
title: INDEX – ดึงแถวตามตำแหน่งภายในเพาร์ติชัน
url: https://www.thepexcel.com/functions/dax/filter/index-dax/
type: function-explainer
program: DAX
syntax: "INDEX(<Position>, <Relation>[, <OrderBy>[, <PartitionBy>[, <MatchBy>[, <Blanks>[, <Reset>]]]]])"
date: 2025-12-13
updated: 2025-12-25
scores:
  popularity: 5
  difficulty: 4
  usefulness: 5
---

# INDEX – ดึงแถวตามตำแหน่งภายในเพาร์ติชัน

> INDEX ดึงแถวจากตำแหน่งที่ระบุ (Position) ภายในกลุ่มข้อมูลที่เรียงแล้ว โดยสามารถใช้ ORDERBY และ PARTI

## คำอธิบาย

INDEX ดึงแถวจากตำแหน่งที่ระบุ (Position) ภายในกลุ่มข้อมูลที่เรียงแล้ว โดยสามารถใช้ ORDERBY และ PARTITIONBY เพื่อควบคุมลำดับและการแบ่งกลุ่ม เหมาะสำหรับงาน window function เช่นดึงค่าอันดับที่ N

## Syntax

```excel
INDEX(&lt;Position&gt;, &lt;Relation&gt;[, &lt;OrderBy&gt;[, &lt;PartitionBy&gt;[, &lt;MatchBy&gt;[, &lt;Blanks&gt;[, &lt;Reset&gt;]]]]])
```

**Variant**

```excel
INDEX(&lt;Position&gt;, &lt;Relation&gt;, &lt;OrderBy&gt;)
```

ดึงแถวที่ตำแหน่ง N จาก relation ที่ถูกจัดลำดับด้วย ORDERBY

## Arguments

| Name | Required | Type | Default | Description |
| --- | --- | --- | --- | --- |
| Position | Yes | number |  | ตำแหน่งแถวที่ต้องการดึง (1-based integer) ค่าบวก = นับจากแรก (1 = แถวแรก) ค่าลบ = นับจากท้าย (-1 = แถวสุดท้าย) ถ้ากำหนด 0 หรือ BLANK() จะคืนตารางว่าง |
| Relation | No | table | ALLSELECTED() ของคอลัมน์ OrderBy/PartitionBy | ตารางหรือ Table Expression ที่ต้องการดึงแถว ถ้าไม่ระบุจะใช้ ALLSELECTED() ของคอลัมน์ใน OrderBy และ PartitionBy |
| OrderBy | No | orderby | ไม่ระบุ | นิพจน์ ORDERBY() เพื่อกำหนดลำดับของแถว มีรูปแบบ ORDERBY(Column1, ASC/DESC, Column2, ASC/DESC, ...) ถ้าไม่ระบุ Relation จะต้องระบุ OrderBy |
| PartitionBy | No | partitionby | ไม่ระบุ (ถือว่า 1 partition) | นิพจน์ PARTITIONBY() เพื่อแบ่งข้อมูลเป็นกลุ่ม INDEX จะดึงตำแหน่งภายในแต่ละกลุ่ม ถ้าไม่ระบุจะถือว่าข้อมูลทั้งหมดเป็น 1 กลุ่ม |
| MatchBy | No | matchby | ไม่ระบุ | นิพจน์ MATCHBY() สำหรับระบุคอลัมน์ที่ใช้ในการแมตช์เพื่อระบุแถวปัจจุบัน ใช้ในงาน Visual Calculations |
| Blanks | No | text | DEFAULT | วิธีจัดการค่า BLANK() ใน OrderBy: DEFAULT (เริ่มต้น), FIRST (ค่า BLANK มาแรก), LAST (ค่า BLANK มาท้าย) |
| Reset | No | text | ไม่ระบุ | ควบคุมการ Reset ที่ hierarchy level ต่างๆ ใช้ใน Visual Calculations เท่านั้น |

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

### ดึงวันที่แรกในช่วงที่เลือกด้วยการจัดลำดับ

ใช้ INDEX(1, ...) เพื่อดึงแถวแรกจากชุดวันที่ที่เลือก

_เหมาะกับ:_ first-row-by-order

### หาอันดับที่ N ภายในกลุ่ม

ใช้ PARTITIONBY เพื่อดึงแถวตำแหน่ง N ในแต่ละกลุ่ม

_เหมาะกับ:_ nth-row-per-group

## ตัวอย่าง

### 1. ตัวอย่างที่ 1: ดึงเดือนแรกในช่วงการเลือก (Basic)

```excel
เดือนแรก =
VAR FirstMonth =
    INDEX(
        1,
        ALLSELECTED(Date[MonthName]),
        ORDERBY(Date[MonthSequence], ASC)
    )
RETURN
    MINX(FirstMonth, Date[MonthName])
```

**ผลลัพธ์:** `ได้ชื่อเดือนแรกในช่วงที่เลือก`

INDEX คืนตาราง 1 แถว ใช้ MINX เพื่อดึงค่า Date[MonthName] ออกมาเป็นข้อความ Position=1 หมายถึงแถวแรกตามลำดับ ORDERBY

### 2. ตัวอย่างที่ 2: ดึงยอดขายจากเดือนสุดท้าย (Negative Position)

```excel
ยอดขายเดือนสุดท้าย =
VAR LastMonthSales =
    CALCULATE(
        [Total Sales],
        INDEX(
            -1,
            ORDERBY(Date[DateKey], DESC)
        )
    )
RETURN
    LastMonthSales
```

**ผลลัพธ์:** `ได้ยอดขายรวมของเดือนสุดท้ายในลำดับ`

Position = -1 เลือกแถวสุดท้าย CALCULATE ใช้ Relation ที่ INDEX คืนมา เพื่อคำนวณ [Total Sales] ในบริบทนั้น

### 3. ตัวอย่างที่ 3: อันดับสูงสุดต่อหมวดสินค้า (PARTITIONBY)

```excel
ยอดขายอันดับ 1 ต่อหมวด =
VAR Top1PerCategory =
    INDEX(
        1,
        SUMMARIZECOLUMNS(
            Product[Category],
            Product[ProductID],
            "Sales", [Total Sales]
        ),
        ORDERBY([Sales], DESC),
        PARTITIONBY(Product[Category])
    )
RETURN
    MINX(Top1PerCategory, [Sales])
```

**ผลลัพธ์:** `ได้ยอดขายสูงสุดในแต่ละหมวดสินค้า`

PARTITIONBY แบ่งให้ SUMMARIZECOLUMNS เป็นกลุ่มตาม Category INDEX เลือก Position 1 (สูงสุด) ภายในแต่ละกลุ่ม ORDERBY [Sales] DESC เรียงจากมากไปน้อย

### 4. ตัวอย่างที่ 4: เปรียบเทียบกับเดือนก่อนหน้า (YoY Pattern)

```excel
เปรียบเทียบเดือนก่อน =
VAR PreviousMonth =
    CALCULATE(
        [Total Sales],
        INDEX(
            -2,
            ORDERBY(Date[MonthSequence], DESC)
        )
    )
VAR ThisMonth = [Total Sales]
RETURN
    IF(ISBLANK(PreviousMonth), BLANK(), ThisMonth - PreviousMonth)
```

**ผลลัพธ์:** `ความแตกต่างยอดขายระหว่างเดือนนี้กับ 2 เดือนก่อน`

Position = -2 ดึงแถวที่ 2 จากท้าย (เดือนก่อนหน้า) เมื่อเทียบกับเดือนปัจจุบัน IF ป้องกัน BLANK ในช่วงเริ่มต้น

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

- ผมแนะนำให้ใช้ VAR เพื่อเก็บผลลัพธ์ INDEX ก่อน เพราะ INDEX คืนตาราง ต้องใช้ iterator แล้วค่อยใช้ในสูตรหลัก จะทำให้อ่านง่ายและ Debug ได้สะดวก

- ระวังเรื่อง Cardinality เมื่อใช้ INDEX ภายใน PARTITIONBY บางทีคอลัมน์ที่ใช้ OrderBy อาจได้มาจากการ Summarize ซึ่งอาจเปลี่ยนความสัมพันธ์ของตาราง ทำให้ผลลัพธ์ไม่ตรงคาด

- ส่วนตัวผม ผมมักใช้ INDEX กับ ORDERBY(Date[Date], DESC) เพื่อดึงข้อมูลย้อนหลังแบบตรงตัว มันง่ายกว่า EARLIER() และ Context Transition ขึ้นเยอะ

- ถ้าต้องการตรวจสอบว่า INDEX คืนตารางว่างหรือไม่ ให้ใช้ ISBLANK(MINX(...)) แทน COUNTROWS เพราะ COUNTROWS ของตารางว่างคือ 0 ซึ่งเขียนเงื่อนไข IF ได้ง่ายกว่า

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

**Q: INDEX คืนค่าเป็นตารางหรือค่าเดี่ยว?**

INDEX คืนค่าเป็นตาราง (row table) ที่มี 1 แถว ถ้าต้องการค่าเดี่ยวให้ใช้ iterator เช่น MINX, MAXX, CONCATENATEX หรือ SELECTCOLUMNS เพื่อดึงคอลัมน์ที่ต้องการออกมา การใช้ INDEX ใน CALCULATE โดยตรงจะทำให้ filter context ของตาราง row นั้น ใช้ได้

**Q: INDEX กับ OFFSET ต่างกันอย่างไร?**

INDEX ดึง "ตำแหน่งแบบสัมบูรณ์" (เช่นแถวที่ 3 หรือแถวสุดท้าย) ส่วน OFFSET ดึง "ตำแหน่งแบบสัมพัทธ์" (เช่น N แถวหลังจากแถวปัจจุบัน) INDEX ใช้ ORDERBY/PARTITIONBY ส่วน OFFSET ใช้ MATCHBY เพื่อระบุจุดเริ่มต้น นอกจากนี้ INDEX คืนตารางทั้งแถว ส่วน OFFSET อาจคืนค่าเดี่ยวได้

**Q: INDEX คืนตารางว่าง (empty table) เมื่อไร?**

เมื่อ Position = 0, Position = BLANK(), หรือ Position เลยนอกช่วง (เช่น Position = 100 แต่มีแถวแค่ 50) INDEX จะคืนตารางว่าง ผมแนะนำให้ใช้ ISBLANK() หรือ COALESCE() เพื่อตรวจสอบและแสดงค่าเริ่มต้นแทน

**Q: PARTITIONBY จำเป็นไหม?**

ไม่จำเป็น ถ้าไม่ระบุ PARTITIONBY INDEX จะถือว่าข้อมูลทั้งหมดเป็น 1 partition ใช้ PARTITIONBY เมื่อต้องการดึงตำแหน่งภายในแต่ละกลุ่ม เช่น ผ่านแต่ละหมวดสินค้า/แต่ละอาคม/แต่ละลูกค้า

**Q: INDEX จำเป็นต้องใช้ ORDERBY ไหม?**

ไม่จำเป็น ถ้าไม่ระบุ ORDERBY INDEX จะใช้ลำดับเริ่มต้นของตารางทีเลือก แต่ส่วนมากจะระบุ ORDERBY เพื่อควบคุมลำดับให้แน่นอน ผมแนะนำให้ระบุ ORDERBY เสมอเพื่อหลีกเลี่ยงข้อผิดพลาด

**Q: INDEX ใช้ได้กับ Calculated Column ไหม?**

ได้ แต่ต้องระวัง INDEX ใน Calculated Column ของตาราง Fact มักจะสูญเสีย Filter Context ที่ Row Level ดังนั้นจึงต้องใช้ ALLSELECTED() หรือ CALCULATETABLE() เพื่อสร้าง Relation ที่ถูกต้อง

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

- offset-dax
- window
- orderby
- partitionby
- allselected
- summarizecolumns
- minx
- maxx
- selectcolumns
- concatenatex

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

- [DAX.guide - INDEX](https://dax.guide/index/) _(guide)_
- [Microsoft Learn - INDEX function](https://learn.microsoft.com/en-us/dax/index-function-dax) _(official)_
- [SQLBI - Window Functions Pattern](https://www.sqlbi.com/articles/window-functions-in-dax/) _(guide)_

---

_Source: [https://www.thepexcel.com/functions/dax/filter/index-dax/](https://www.thepexcel.com/functions/dax/filter/index-dax/)_
