Thep Excel

DISTINCTดึงรายการที่ไม่ซ้ำ (Unique Values) พร้อมหลีกหนีค่า Blank Row

DISTINCT คืนค่าตารางที่มีคอลัมน์เดียว ซึ่งประกอบด้วยค่าที่ไม่ซ้ำกันจากคอลัมน์ที่ระบุ โดยไม่รวม Blank Row ที่เกิดจาก Invalid Relationship ความแตกต่างหลักจาก VALUES คือ DISTINCT จะซ่อน Data Quality Issues ในขณะที่ VALUES จะเตือนให้เห็น

fx
=DISTINCT( <column> )

ความนิยม7/10
ความยาก3/10
ประโยชน์7/10

อัปเดต 13 December 2025

Syntax & Arguments

อาร์กิวเมนต์ ชนิด คำอธิบาย
column column คอลัมน์ที่ต้องการดึงค่าที่ไม่ซ้ำ หรือนิพจน์ที่คืนค่าเป็นคอลัมน์ เช่น Sales[ProductID] หรือ RELATED(Products[Category])

Additional Notes

DISTINCT คือฟังก์ชันที่ใช้สำหรับดึงรายการข้อมูลที่ไม่ซ้ำกัน (Unique/Distinct Values) ออกมาจากคอลัมน์หรือตารางที่ระบุ โดยจะตัดรายการที่ซ้ำกันออกให้เหลือเพียงรายการเดียว

DISTINCT คืนค่าเป็นตารางชั่วคราว (ไม่ใช่ List) ดังนั้นต้องใช้ COUNTROWS, SUMX, หรือ FILTER ร่วมด้วยเสมอ

ส่วนตัวผมเห็นว่า VALUES และ DISTINCT ทำให้สับสนง่ายมากในชุมชน DAX ที่เป็นจริงคือ:
– **DISTINCT**: “หลีกหนี” Blank Row จาก Invalid Relationship (ข้อมูลสกปรก)
– **VALUES**: “เตือน” เมื่อเจอ Blank Row (ข้อมูลไม่ตรง)

ในทางปฏิบัติ ผมแนะนำให้ใช้ VALUES เพราะมันช่วยดักจับ Data Quality Issues แต่ถ้าข้อมูลสะอาดอยู่แล้ว ผลลัพธ์ของทั้งสองจะเหมือนกัน 😎

**ฟังก์ชันนี้ทำงานใน:**
– Calculated Columns (รับ Row Context)
– Calculated Tables (ดึงตารางชั่วคราว)
– Measures (ไม่มี Row Context ตอนหลัก)
– Visual Calculations (Power BI 2024+)

**คำเตือน:** ผลลัพธ์ของ DISTINCT ไม่ใช่ Additive – รวมค่า Distinct Count ของแต่ละกลุ่มจะไม่เท่ากับ Distinct Count ทั้งหมด

How it works

การนำไปใช้เป็น Iterator

ใช้สร้างตารางรายการสินค้าที่ไม่ซ้ำ เพื่อนำไปวนลูปคำนวณต่อใน SUMX หรือ AVERAGEX

การนับจำนวนแบบไม่ซ้ำ (Manual)

ใช้ COUNTROWS ครอบ DISTINCT เพื่อจำลองการทำงานของ DISTINCTCOUNT (แต่ DISTINCTCOUNT เร็วกว่า)

Examples

ตัวอย่างที่ 1: นับลูกค้าไม่ซ้ำในแต่ละเดือนUnique Customers = COUNTROWS( DISTINCT( Sales[CustomerID] ) )

DISTINCT ดึงรายการลูกค้าที่ไม่ซ้ำออกมา แล้วใช้ COUNTROWS นับจำนวนแถว ผลลัพธ์ขึ้นกับ Filter Context (เดือน ปี ภูมิภาค ฯลฯ)

fx
Unique Customers = COUNTROWS( DISTINCT( Sales[CustomerID] ) )

ผลลัพธ์จำนวนลูกค้าทั่วไป (ตัวอักษร) – หาก Filter Context เลือกเดือนมีนา ก็ได้แค่ลูกค้าในเดือนนั้น
ตัวอย่างที่ 2: ดึงรหัสสินค้าจากตารางข้อมูล SalesUnique Products = DISTINCT( Sales[ProductCode] )

แม้ใน Sales จะมี ProductCode A001 ปรากฏ 500 ครั้ง DISTINCT ก็จะคืนค่า A001 เพียงแถวเดียว (ตารางแบบ Read-Only)

fx
Unique Products = DISTINCT( Sales[ProductCode] )

ผลลัพธ์ตารางชั่วคราวประกอบด้วยรหัสสินค้า (ไม่ซ้ำ) ที่มีการขายจริง
ตัวอย่างที่ 3: เปรียบเทียบ DISTINCT vs VALUESDistinct Count = COUNTROWS( DISTINCT( Sales[ProductID] ) ) Values Count = COUNTROWS( VALUES( Sales[ProductID] ) )

ถ้าเสิร์ฟเวอร์ Sales มีรหัสสินค้าที่ไม่มีใน Product Master (Invalid Relationship) VALUES จะส่ง Blank Row แต่ DISTINCT จะซ่อนมันไป

fx
Distinct Count = COUNTROWS( DISTINCT( Sales[ProductID] ) )
Values Count = COUNTROWS( VALUES( Sales[ProductID] ) )

ผลลัพธ์DISTINCT: 50 | VALUES: 51 (ทั้ง 50 สินค้า + 1 Blank จากข้อมูลสกปรก)
ตัวอย่างที่ 4: ใช้ DISTINCT ใน Calculated TableList of Categories = DISTINCT( Products[Category] )

สร้างตารางวิมัติเพื่อให้ Report ใช้เป็น Filter Dropdown ถ้าข้อมูล Products มี Duplicate Categories จะถูกตัดออก

fx
List of Categories = DISTINCT( Products[Category] )

ผลลัพธ์ตารางคงที่สรุปรายการหมวดหมู่สินค้าไม่ซ้ำ (Electronics, Furniture, Clothing ฯลฯ)

FAQs

ควรใช้ DISTINCT หรือ VALUES?+

โดยทั่วไปแนะนำให้ใช้ VALUES เพราะหากมีความสัมพันธ์ที่ผิดพลาด (เช่น ขายสินค้าที่ไม่มีใน Master) การใช้ VALUES จะทำให้เราเห็น Blank Row ซึ่งช่วยเตือนว่ามีข้อมูลหาย แต่ DISTINCT จะซ่อนปัญหานั้นไว้ ผมเห็นว่า VALUES ปลอดภัยกว่าสำหรับ Data Quality

DISTINCT คืนค่าอะไร – เลขตัวเดียวหรือตาราง?+

DISTINCT คืนค่าเป็น **ตาราง** (มี 1 คอลัมน์) ไม่ใช่ตัวเลขตัวเดียว ดังนั้นต้องใช้ COUNTROWS, FILTER, SUMX ร่วมด้วยเสมอ ถ้าพยายามใช้โดยลำพัง จะได้ error 'Cannot display' หรือ ได้ค่าแปลกๆ

ผลลัพธ์ของ DISTINCT ตอบรับ Filter Context หรือไม่?+

ใช่แน่นอน ถ้า Report เลือก 'March 2025' ผลลัพธ์ของ COUNTROWS(DISTINCT(…)) จะนับแต่ลูกค้าที่ซื้อในเดือนมีนา เพราะ Filter Context กรองข้อมูล Sales ลงมาแล้ว

ใช้ DISTINCT ในหลายคอลัมน์ได้ไหม เช่น DISTINCT(Sales[ProductID], Sales[Date])?+

ไม่ได้ DISTINCT รับได้แค่ 1 อาร์กิวเมนต์เท่านั้น ถ้าต้องการ Unique Combination ให้ใช้ DISTINCT( Sales ) (ตารางทั้งหมด) หรือใช้ GROUPBY กับ SUMMARIZE แทน

Resources & Related

ฟังก์ชันที่ผู้เขียนโยงไว้กับ DISTINCT จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง

ฟังก์ชันนี้DISTINCTTable manipulation
Table manipulation (6)
EXCEPT

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

INTERSECT

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

SELECTCOLUMNS

สร้างตารางใหม่โดยเลือกเฉพาะคอลัมน์ที่ต้องการจากตารางต้นฉบับและเพิ่มคอลัมน์ที่คำนวณได้ ต่างจาก ADDCOLUMNS ตรงที่ SELECTCOLUMNS เริ่มจากตารางว่างแล้วเพิ่มเฉพาะคอลัมน์ที่ระบุ ทำให้สามารถปรับโครงสร้างตารางและเลือกข้อมูลที่จำเป็นได้อย่างยืดหยุ่น

SUMMARIZE

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 ดีกว่าอย่างมาก

UNION

UNION รวมหลายตารางให้เป็นตารางเดียวด้วยการต่อแถว โดยเก็บแถวซ้ำไว้ทั้งหมด เหมาะกับการรวมชุดข้อมูลที่มีโครงสร้างคอลัมน์สอดคล้องกัน

VALUES

VALUES ดึงค่าที่ไม่ซ้ำจากคอลัมน์ หรือดึงแถวทั้งหมดจากตาราง โดยรวมแถว BLANK ที่เกิดจากข้อผิดพลาดของความสัมพันธ์ (Referential Integrity Violations) ส่วน DISTINCT จะไม่รวมแถว BLANK นี้

Filter (2)
ALL

ALL มีพฤติกรรมแตกต่างกัน 2 แบบ: ใช้เป็น Table Expression จะคืนทุกแถวในตาราง หรือทุกค่าในคอลัมน์ โดยไม่สนใจ Filter ใดๆ เหมาะสำหรับใช้ร่วมกับ FILTER, COUNTROWS, SUMMARIZE หรือใช้เป็น CALCULATE Modifier เพื่อลบ Filter ออกจากตารางหรือคอลัมน์ที่ระบุ ทำให้สามารถคำนวณ Grand Total หรือหาเปอร์เซ็นต์เทียบกับยอดรวมได้

CALCULATETABLE

CALCULATETABLE evaluate table expression ภายใต้ filter context ที่ถูกปรับเปลี่ยน แล้วคืนค่าเป็น table (ตาราง) ซึ่งแตกต่างจาก CALCULATE ที่คืนค่าเป็น scalar value รองรับ filter arguments 3 รูปแบบ: Boolean expression, table expression, และ filter modifier functions (REMOVEFILTERS, ALL, KEEPFILTERS, USERELATIONSHIP, CROSSFILTER) มีพฤติกรรมเหมือน CALCULATE ในทุกแง่มุมของการจัดการ filter context รวมถึง context transition แต่เหมาะสำหรับการสร้าง intermediate table ที่ถูกกรองแล้วส่งต่อให้ iterator functions หรือใช้ใน calculated table มักมี performance ดีกว่า FILTER ใน simple filtering scenarios เพราะ DAX engine สามารถทำ cardinality estimation และ optimization ได้ดีกว่า

Aggregation (2)
COUNTROWS

COUNTROWS เป็นฟังก์ชันการรวม (Aggregation) ที่นับจำนวนแถวในตารางที่ระบุ ไม่ว่าจะเป็นตารางจริงในโมเดลหรือตารางเสมือน (Virtual Table) จากฟังก์ชันอื่นๆ เช่น FILTER, VALUES, DISTINCT นับเท่าไหร่? ผลลัพธ์ก็คือจำนวนแถวเต็ม ๆ

DISTINCTCOUNT

DISTINCTCOUNT นับจำนวนค่าที่แตกต่างกันทั้งหมดในคอลัมน์ รวมถึง BLANK values ถ้าไม่มีแถวข้อมูล จะคืนค่า BLANK

Comments

อีเมลของคุณจะไม่ถูกเผยแพร่