FILTER ใช้กรองแถวในตารางตามเงื่อนไขที่ซับซ้อน โดยวนลูปทุกแถวและประเมินเงื่อนไข เหมาะกับการกรองด้วย Measure หรือ Expression ซึ่ง Boolean Expression ทำไม่ได้ แต่ต้องระวังเรื่อง Performance เพราะเป็น Iterator Function ที่ช้ากว่า Boolean Expression ดังนั้นควรใช้เฉพาะเมื่อจำเป็น และอย่าใช้ FILTER กับ RELATED เพื่อกรองข้ามตาราง ให้กรองที่ Dimension Table โดยตรงแทน
=FILTER(<table>, <filter>)
=FILTER(<table>, <filter>)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| table | table | Yes | ตารางหรือ Table Expression ที่ต้องการกรอง เช่น Sales, Products, ALL(Customers), VALUES(Products[Category]) | |
| filter | boolean | Yes | เงื่อนไขที่ใช้กรอง ต้องคืนค่า TRUE หรือ FALSE สำหรับแต่ละแถว รองรับ Measure, Expression, และ RELATED() |
ใช้ FILTER กรองด้วย Measure เช่น [Total Sales] > 50000 ซึ่งเป็นค่าที่คำนวณจาก SUM() ไม่ใช่คอลัมน์จริง Boolean Expression ทำไม่ได้
ใช้ FILTER กรองด้วย Expression ที่คำนวณจากหลายคอลัมน์ เช่น Products[Price] * Products[Quantity] > 1000 ซึ่งเป็นค่าที่ไม่มีอยู่ใน Data Model
ใช้ FILTER กรองด้วยหลายเงื่อนไขแบบ OR เช่น Products[Category] = "Electronics" || Products[Category] = "Appliances" ซึ่ง Boolean Expression เดี่ยวๆ ทำไม่ได้
// สมมติตาราง Products มีสินค้าสีแดง 5 รายการ // ยอดขายสินค้าสีแดงรวม = 45,800 // Boolean Expression (แนะนำ - เร็วกว่า) Red Products Sales = CALCULATE( SUM(Sale…// สมมติตาราง Products มีสินค้าสีแดง 5 รายการ
// ยอดขายสินค้าสีแดงรวม = 45,800
// Boolean Expression (แนะนำ - เร็วกว่า)
Red Products Sales =
CALCULATE(
SUM(Sales[Amount]),
Products[Color] = "Red" // ใช้แบบนี้แทน FILTER
)
45,800 (ยอดขายสินค้าสีแดง)
// สมมติตาราง Products มี 100 สินค้า // มี 15 สินค้าที่ยอดขายเกิน 50,000 // Measure สำหรับคำนวณยอดขายต่อสินค้า Total Sales = SUM(Sales[Amount]) // นับสินค้าที่ข…// สมมติตาราง Products มี 100 สินค้า
// มี 15 สินค้าที่ยอดขายเกิน 50,000
// Measure สำหรับคำนวณยอดขายต่อสินค้า
Total Sales =
SUM(Sales[Amount])
// นับสินค้าที่ขายได้มากกว่า 50,000
Top Products Count =
CALCULATE(
COUNTROWS(Products),
FILTER(
Products,
[Total Sales] > 50000
)
)
15 (จำนวนสินค้าที่มียอดขายเกิน 50,000)
// สมมติตาราง Sales มี 1,000 รายการ // มี 145 รายการที่ Quantity * UnitPrice > 10,000 // นับ Order ที่มูลค่ารวมเกิน 10,000 High Value Orders = CALCULATE( COUNTR…// สมมติตาราง Sales มี 1,000 รายการ
// มี 145 รายการที่ Quantity * UnitPrice > 10,000
// นับ Order ที่มูลค่ารวมเกิน 10,000
High Value Orders =
CALCULATE(
COUNTROWS(Sales),
FILTER(
Sales,
Sales[Quantity] * Sales[UnitPrice] > 10000
)
)
145 (จำนวน Order ที่มูลค่าเกิน 10,000)
// สมมติ Sales เชื่อมกับ Products ด้วย ProductKey // ยอดขาย Electronics = 2,500,000 // ✅ วิธีถูก: กรองที่ Dimension Table โดยตรง Electronics Sales = CALCULATE(…// สมมติ Sales เชื่อมกับ Products ด้วย ProductKey
// ยอดขาย Electronics = 2,500,000
// ✅ วิธีถูก: กรองที่ Dimension Table โดยตรง
Electronics Sales =
CALCULATE(
SUM(Sales[Amount]),
Products[Category] = "Electronics" // Boolean Expression
)
// ❌ หลีกเลี่ยง: FILTER(Sales, RELATED(Products[Category]) = ...)
// ช้ามาก (วนลูปหลักแสนแถว) และอาจให้ผลผิด!
2,500,000 (ยอดขายสินค้า Electronics)
ใช้ Boolean Expression เสมอที่ทำได้ เพราะได้ Columnar Storage Optimization ทำให้เร็วกว่า 100+ เท่า
.
ใช้ FILTER เฉพาะเมื่อ “จำเป็น” กรณีเหล่านี้:
1. กรองด้วย Measure – เช่น [Total Sales] > 50000 (ค่าที่ต้องคำนวณ)
2. กรองด้วย Virtual Column/Expression – เช่น Price * Quantity > 1000 (คอลัมน์เสมือน)
3. กรองหลายเงื่อนไขด้วย OR – เช่น Category = “A” || Category = “B”
.
⚠️ สำคัญ: อย่าใช้ FILTER + RELATED เพื่อกรองข้ามตาราง! ให้กรองที่ Dimension Table โดยตรงแทน เช่น Products[Category] = “Electronics” แทนที่จะใช้ FILTER(Sales, RELATED(Products[Category]) = “Electronics”) 💡
จริงครับ เพราะ FILTER เป็น Iterator Function ที่วนลูปทีละแถวและประเมินเงื่อนไข
.
ถ้าใช้กับตารางขนาดใหญ่เช่น Fact Table หลักแสนแถว จะช้ามาก ส่วน Boolean Expression ได้ Columnar Storage Optimization ทำให้เร็วกว่า
.
ส่วนตัวผมแนะนำไม่ให้ใช้ FILTER กับ Fact Table โดยตรง ถ้าทำได้ให้ใช้กับ Dimension Table แทน (เช่น Products, Customers) ซึ่งมีแถวน้อยกว่า 😅
ใช่ครับ ภายในเครื่อง DAX จะแปลง Boolean Expression เป็น FILTER(ALL(Column), condition) อัตโนมัติ
.
แต่จะได้ Columnar Storage Optimization ทำให้เร็วมาก ส่วน FILTER ที่เขียนเอง จะไม่ได้ Optimization นี้ นี่คือเหตุผลที่ Boolean Expression เร็วกว่า FILTER มาก
.
ที่เจ๋งคือ DAX Engine ฉลาดพอที่จะ optimize ให้เราเอง แค่เราเขียนให้ถูกรูปแบบ 💡
ต้องระวังเรื่อง KEEPFILTERS ถ้าใช้ FILTER ใน CALCULATE โดยตรง มันจะ “เขียนทับ” Filter Context ที่มีอยู่เดิม (เช่น Filter จากผู้ใช้เลือกใน Slicer)
.
ถ้าต้องการ “รวม” Filter แทนการเขียนทับ ให้ใช้ KEEPFILTERS ห่อไว้:
CALCULATE(…, KEEPFILTERS(FILTER(…)))
.
นี่สำคัญมากในการทำ Dashboard ที่มี User Interaction ส่วนตัวผมใช้ KEEPFILTERS บ่อยมากครับ 😎
ทั้งคู่ใช้กรองตารางได้เหมือนกัน แต่ CALCULATETABLE จะแปลงเงื่อนไขเป็น FILTER หลายตัวแยกกันตามคอลัมน์ ซึ่งบางกรณีเร็วกว่า
.
เอาจริงๆ Microsoft แนะนำว่า “อย่าคิดว่า CALCULATETABLE ดีกว่า FILTER เสมอไป” เพราะ Performance ขึ้นอยู่กับ Cardinality และ Granularity ของข้อมูล
.
ส่วนตัวผมใช้ FILTER เมื่อต้องการ control logic เอง และใช้ CALCULATETABLE เมื่อมีหลายเงื่อนไขที่เป็นอิสระต่อกัน
FILTER เป็นฟังก์ชันที่ใช้กรองแถวในตารางตามเงื่อนไขที่กำหนด โดยจะวนลูปทุกแถวแล้วประเมินเงื่อนไขทีละแถว (Row-by-row evaluation) แล้วคืนค่าเป็นตารางที่มีเฉพาะแถวที่ผ่านเงื่อนไข
.
ที่เจ๋งคือ FILTER สามารถใช้เงื่อนไขที่ซับซ้อนได้ เช่น กรองด้วย Measure หรือ Expression ที่คำนวณจากหลายคอลัมน์ ซึ่ง Boolean Expression ธรรมดาทำไม่ได้
.
แต่ที่ต้องระวังคือ FILTER เป็น Iterator Function ที่ประมวลผลทีละแถว ดังนั้นถ้าใช้กับตารางขนาดใหญ่อาจทำงานช้า Microsoft แนะนำให้ใช้ Boolean Expression แทนเสมอที่ทำได้ เพราะได้ Columnar Storage Optimization ทำให้เร็วกว่ามาก
.
ส่วนตัวผมใช้ FILTER เฉพาะเมื่อ “จำเป็น” จริงๆ เช่น กรองด้วย Measure ([Total Sales] > 50000) หรือ Virtual Column (Products[Price] * Products[Quantity] > 1000) ซึ่งเป็นค่าที่ไม่มีอยู่ใน Data Model 😎
Boolean Expression ใน CALCULATE ไม่รองรับกรณีเหล่านี้:
.
1. Measure – กรองด้วยค่าที่ต้องคำนวณ เช่น [Total Sales] > 50000
2. Virtual Column/Expression – กรองด้วยสูตรคำนวณ เช่น Products[Price] * Products[Quantity] > 1000
3. OR Condition – กรองด้วยหลายเงื่อนไขแบบ OR เช่น Products[Category] = “A” || Products[Category] = “B”
.
เรียกได้ว่า “ใช้ FILTER เมื่อกรองด้วยสิ่งที่ Boolean Expression ทำไม่ได้” 💡
กฎทองที่สำคัญที่สุดใน DAX คือ “กรองคอลัมน์ ไม่ใช่กรองตาราง” (Filter Columns, Not Tables)
.
❌ อย่าทำ: FILTER(Sales, RELATED(Products[Category]) = “Electronics”) – ช้ามาก และอาจให้ผลผิด!
✅ ให้ทำ: Products[Category] = “Electronics” – กรองที่ Dimension Table โดยตรง เร็วกว่า 100+ เท่า
.
เมื่อใช้ FILTER กับตาราง จะกรอง “expanded table” ที่รวม dimension ทุกตัว อาจทำให้ได้ผลลัพธ์ไม่ถูกต้อง ดังนั้น อย่าใช้ FILTER + RELATED เพื่อกรองข้ามตาราง ให้กรองที่ Dimension Table โดยตรงแทน!