---
title: EXCEPT – หาผลต่างของตาราง (อยู่ในซ้ายแต่ไม่อยู่ในขวา)
url: https://www.thepexcel.com/functions/dax/table-manipulation/except-dax/
type: function-explainer
program: DAX
syntax: "EXCEPT(<LeftTable>, <RightTable>)"
date: 2025-12-13
updated: 2025-12-25
scores:
  popularity: 5
  difficulty: 4
  usefulness: 5
---

# EXCEPT – หาผลต่างของตาราง (อยู่ในซ้ายแต่ไม่อยู่ในขวา)

> EXCEPT คืนตารางของแถวที่อยู่ใน LeftTable แต่ไม่อยู่ใน RightTable เหมาะกับการหาสิ่งที่ขาดหาย เช่น สิน

## คำอธิบาย

EXCEPT คืนตารางของแถวที่อยู่ใน LeftTable แต่ไม่อยู่ใน RightTable เหมาะกับการหาสิ่งที่ขาดหาย เช่น สินค้าที่ไม่เคยขาย ลูกค้าที่ไม่มีธุรกรรม

## Syntax

```excel
EXCEPT(&lt;LeftTable&gt;, &lt;RightTable&gt;)
```

**Variant**

```excel
EXCEPT(&lt;LeftTable&gt;, &lt;RightTable&gt;)
```

คืนแถวที่อยู่ใน LeftTable แต่ไม่อยู่ใน RightTable

## Arguments

| Name | Required | Type | Default | Description |
| --- | --- | --- | --- | --- |
| LeftTable | Yes | table |  | ตารางฝั่งซ้าย (ชุดหลักที่เป็นฐาน) โดยทั่วไปใช้ VALUES() หรือ FILTER() ที่ได้จากตารางหลักอย่าง Products หรือ Customers |
| RightTable | Yes | table |  | ตารางฝั่งขวา (ชุดที่ต้องการตัดออก) โดยทั่วไปคือข้อมูลที่เกิดจริง เช่น VALUES(Sales[ProductID]) ที่บอกว่า "สินค้าไหนที่มีการขาย" |

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

### หาสินค้าที่ไม่เคยขาย

เอารายการสินค้าทั้งหมด ลบด้วยรายการสินค้าที่เคยปรากฏในยอดขาย

_เหมาะกับ:_ missing-products

### หาลูกค้าที่ไม่มีธุรกรรม

เทียบรายชื่อลูกค้ากับรายชื่อลูกค้าที่ปรากฏในตารางขาย

_เหมาะกับ:_ inactive-customers

## ตัวอย่าง

### 1. ตัวอย่างที่ 1: สินค้าที่ไม่เคยขาย

```excel
VAR AllProducts = VALUES(Products[ProductID])
VAR ProductsSold = VALUES(Sales[ProductID])
RETURN
EXCEPT(AllProducts, ProductsSold)
```

**ผลลัพธ์:** `ได้รายการ ProductID ของสินค้าทั้งหมดที่อยู่ในตาราง Products แต่ไม่พบในยอดขาย`

ขั้นแรก สร้าง AllProducts จากตาราง Products ได้ทุกสินค้า ขั้นที่สอง สร้าง ProductsSold จากตาราง Sales ได้สินค้าที่มีการขายจริง ขั้นที่สาม ใช้ EXCEPT ลบ ProductsSold ออกจาก AllProducts ได้สินค้าที่หายไป

### 2. ตัวอย่างที่ 2: ลูกค้าที่ไม่มีรายการขายในเดือนนี้

```excel
VAR AllCustomers = VALUES(Customers[CustomerID])
VAR BuyersThisMonth = VALUES(FILTER(Sales, MONTH(Sales[Date]) = MONTH(TODAY())))
VAR BuyerCustomers = VALUES(BuyersThisMonth[CustomerID])
RETURN
EXCEPT(AllCustomers, BuyerCustomers)
```

**ผลลัพธ์:** `ได้รายชื่อลูกค้าที่ไม่มีการเข้ามาซื้อในเดือนปัจจุบัน`

ใช้ FILTER กรองยอดขายของเดือนปัจจุบันก่อน แล้วดึงรายชื่อลูกค้าจากข้อมูลเบาะแสนั้น จากนั้นใช้ EXCEPT หาลูกค้าที่ยังไม่ปรากฏในฟิลเตอร์นั้น

### 3. ตัวอย่างที่ 3: เปรียบเทียบ EXCEPT กับ INTERSECT

```excel
VAR LeftSet = {1, 2, 3, 4}
VAR RightSet = {3, 4, 5, 6}
VAR OnlyLeft = EXCEPT(LeftSet, RightSet)  -- ได้ {1, 2}
VAR CommonBoth = INTERSECT(LeftSet, RightSet)  -- ได้ {3, 4}
VAR Combined = UNION(LeftSet, RightSet)  -- ได้ {1, 2, 3, 4, 5, 6}
```

**ผลลัพธ์:** `EXCEPT ได้ {1,2} / INTERSECT ได้ {3,4} / UNION ได้ {1,2,3,4,5,6}`

EXCEPT = ซ้ายแต่ไม่อยู่ขวา / INTERSECT = อยู่ทั้งซ้ายและขวา / UNION = รวมทั้งสองฝั่ง เลือกใช้ตามสิ่งที่ต้องการหา

### 4. ตัวอย่างที่ 4: นับสินค้าที่ไม่เคยขาย

```excel
Count of Unsold Products =
VAR AllProducts = VALUES(Products[ProductID])
VAR ProductsSold = VALUES(Sales[ProductID])
RETURN
COUNTROWS(EXCEPT(AllProducts, ProductsSold))
```

**ผลลัพธ์:** `ตัวเลขแสดงจำนวนสินค้าที่ไม่เคยขาย`

ใช้ EXCEPT เพื่อหารายชื่อสินค้าที่ไม่เคยขาย แล้วค่อย COUNTROWS นับจำนวนแถว

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

- ผมแนะนำให้ใช้ VAR เก็บ LeftTable และ RightTable ก่อน แล้วค่อยใช้ EXCEPT ทำให้อ่านง่าย และ debug ง่ายด้วย

- ตัวตั้ง (LeftTable) ควรเป็นข้อมูลที่ "ครบ" หรือ "หลัก" เสมอ เพราะ EXCEPT จะคืนสิ่งที่ไม่มีในตัวลบ ถ้าใจวาง ซ้ายกับขวาสลับกัน ผลลัพธ์จะต่างกันมาก

- EXCEPT ไม่มี Sort เพิ่มเติม ถ้าต้องการจัดเรียงผลลัพธ์ ให้ใช้ ORDERBY ซ้อนไว้หนึ่งชั้น

- หากต้องการตรวจสอบว่ามีสิ่งไหนขาดหายหรือหาสิ่งที่ยังไม่ได้กระทำ EXCEPT + COUNTROWS เป็นชุดค่อนข้างเก่ง

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

**Q: EXCEPT ต่างจาก INTERSECT และ UNION อย่างไร?**

EXCEPT = ซ้ายแต่ไม่อยู่ขวา / INTERSECT = อยู่ในทั้งซ้ายและขวา (ส่วนร่วม) / UNION = รวมทั้งซ้ายและขวาโดยลบของซ้ำ เลือกใช้ตามสิ่งที่หา ผมมักจำได้ว่า EXCEPT คือการลบเซต (difference) จึงใช้เมื่อต้องการหาสิ่งที่ "ขาดหาย"

**Q: ตารางสองฝั่งต้องมีโครงสร้างเหมือนกันหรือไม่?**

จำนวนคอลัมน์ต้องเท่ากัน และเทียบตามตำแหน่ง (position) ไม่ใช่ชื่อ ชนิดข้อมูลควรเข้ากันได้ เพราะ DAX จะเทียบแถวตามค่าและชนิด เช่น ถ้า LeftTable มี 2 คอลัมน์ RightTable ก็ต้อง 2 คอลัมน์เหมือนกัน

**Q: ถ้าตารางซ้ายมีข้อมูลซ้ำ (duplicate) จะเกิดอะไร?**

ถ้า LeftTable มีแถวซ้ำกัน EXCEPT จะเก็บข้อมูลซ้ำนั้นไว้ หากแถวไม่พบใน RightTable เช่น LeftTable = {A, A, B} และ RightTable = {B} ผลลัพธ์จะเป็น {A, A} เพราะ A ทั้งสองแถวไม่พบใน RightTable

**Q: EXCEPT ทำงานบริบทอย่างไร (row context vs filter context)?**

EXCEPT ทำงานเป็น table function ที่ส่งคืน table ไม่ได้ทำการ context transition อัตโนมัติ บริบทที่สร้างตาราง LeftTable และ RightTable ต่างหากที่สำคัญ เช่น ใช้ VALUES() ซึ่งตัดออก row context แล้วสร้างเป็น filter context จึงต้อง VAR เก็บไว้ก่อน

**Q: ใช้ EXCEPT เพื่อเปรียบเทียบหลาย column ได้ไหม?**

ได้ เพียงแต่ต้องสร้าง table ที่มีคอลัมน์หลายตัว เช่น SELECTCOLUMNS ใช้เลือกคอลัมน์ A, B, C จากตัวตั้ง แล้ว EXCEPT จะเทียบแถวทั้ง 3 คอลัมน์พร้อมกัน

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

- intersect
- union
- values
- distinct
- selectcolumns
- [FILTER – กรองตารางด้วยเงื่อนไขที่ซับซ้อน (Iterator Function)](https://www.thepexcel.com/functions/dax/filter/filter-dax/)
- summarize

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

- [DAX.guide - EXCEPT](https://dax.guide/except/) _(guide)_
- [Microsoft Learn - EXCEPT Function](https://learn.microsoft.com/en-us/dax/except) _(official)_

---

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