EXCEPT คืนตารางของแถวที่อยู่ใน LeftTable แต่ไม่อยู่ใน RightTable เหมาะกับการหาสิ่งที่ขาดหาย เช่น สินค้าที่ไม่เคยขาย ลูกค้าที่ไม่มีธุรกรรม
=EXCEPT(<LeftTable>, <RightTable>)
=EXCEPT(<LeftTable>, <RightTable>)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| LeftTable | table | Yes | ตารางฝั่งซ้าย (ชุดหลักที่เป็นฐาน) โดยทั่วไปใช้ VALUES() หรือ FILTER() ที่ได้จากตารางหลักอย่าง Products หรือ Customers | |
| RightTable | table | Yes | ตารางฝั่งขวา (ชุดที่ต้องการตัดออก) โดยทั่วไปคือข้อมูลที่เกิดจริง เช่น VALUES(Sales[ProductID]) ที่บอกว่า “สินค้าไหนที่มีการขาย” |
เอารายการสินค้าทั้งหมด ลบด้วยรายการสินค้าที่เคยปรากฏในยอดขาย
เทียบรายชื่อลูกค้ากับรายชื่อลูกค้าที่ปรากฏในตารางขาย
VAR AllProducts = VALUES(Products[ProductID]) VAR ProductsSold = VALUES(Sales[ProductID]) RETURN EXCEPT(AllProducts, ProductsSold)VAR AllProducts = VALUES(Products[ProductID])
VAR ProductsSold = VALUES(Sales[ProductID])
RETURN
EXCEPT(AllProducts, ProductsSold)
ได้รายการ ProductID ของสินค้าทั้งหมดที่อยู่ในตาราง Products แต่ไม่พบในยอดขาย
VAR AllCustomers = VALUES(Customers[CustomerID]) VAR BuyersThisMonth = VALUES(FILTER(Sales, MONTH(Sales[Date]) = MONTH(TODAY()))) VAR BuyerCustomers = VALUES(Bu…VAR AllCustomers = VALUES(Customers[CustomerID])
VAR BuyersThisMonth = VALUES(FILTER(Sales, MONTH(Sales[Date]) = MONTH(TODAY())))
VAR BuyerCustomers = VALUES(BuyersThisMonth[CustomerID])
RETURN
EXCEPT(AllCustomers, BuyerCustomers)
ได้รายชื่อลูกค้าที่ไม่มีการเข้ามาซื้อในเดือนปัจจุบัน
VAR LeftSet = {1, 2, 3, 4} VAR RightSet = {3, 4, 5, 6} VAR OnlyLeft = EXCEPT(LeftSet, RightSet) -- ได้ {1, 2} VAR CommonBoth = INTERSECT(LeftSet, RightSet) -- ไ…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}
Count of Unsold Products = VAR AllProducts = VALUES(Products[ProductID]) VAR ProductsSold = VALUES(Sales[ProductID]) RETURN COUNTROWS(EXCEPT(AllProducts, Produc…Count of Unsold Products =
VAR AllProducts = VALUES(Products[ProductID])
VAR ProductsSold = VALUES(Sales[ProductID])
RETURN
COUNTROWS(EXCEPT(AllProducts, ProductsSold))
ตัวเลขแสดงจำนวนสินค้าที่ไม่เคยขาย
EXCEPT = ซ้ายแต่ไม่อยู่ขวา / INTERSECT = อยู่ในทั้งซ้ายและขวา (ส่วนร่วม) / UNION = รวมทั้งซ้ายและขวาโดยลบของซ้ำ เลือกใช้ตามสิ่งที่หา ผมมักจำได้ว่า EXCEPT คือการลบเซต (difference) จึงใช้เมื่อต้องการหาสิ่งที่ “ขาดหาย”
จำนวนคอลัมน์ต้องเท่ากัน และเทียบตามตำแหน่ง (position) ไม่ใช่ชื่อ ชนิดข้อมูลควรเข้ากันได้ เพราะ DAX จะเทียบแถวตามค่าและชนิด เช่น ถ้า LeftTable มี 2 คอลัมน์ RightTable ก็ต้อง 2 คอลัมน์เหมือนกัน
ถ้า LeftTable มีแถวซ้ำกัน EXCEPT จะเก็บข้อมูลซ้ำนั้นไว้ หากแถวไม่พบใน RightTable เช่น LeftTable = {A, A, B} และ RightTable = {B} ผลลัพธ์จะเป็น {A, A} เพราะ A ทั้งสองแถวไม่พบใน RightTable
EXCEPT ทำงานเป็น table function ที่ส่งคืน table ไม่ได้ทำการ context transition อัตโนมัติ บริบทที่สร้างตาราง LeftTable และ RightTable ต่างหากที่สำคัญ เช่น ใช้ VALUES() ซึ่งตัดออก row context แล้วสร้างเป็น filter context จึงต้อง VAR เก็บไว้ก่อน
ได้ เพียงแต่ต้องสร้าง table ที่มีคอลัมน์หลายตัว เช่น SELECTCOLUMNS ใช้เลือกคอลัมน์ A, B, C จากตัวตั้ง แล้ว EXCEPT จะเทียบแถวทั้ง 3 คอลัมน์พร้อมกัน
EXCEPT เป็นฟังก์ชันเซตข้อมูล (set operation) ที่ใช้หา “ผลต่าง” ระหว่างสองตาราง คืนแถวทั้งหมดที่อยู่ในตารางฝั่งซ้าย แต่ไม่พบในตารางฝั่งขวา เหมือนแนวคิด A – B ในเซต คอลัมน์จะเทียบกันตามตำแหน่ง (position) ไม่ใช่ชื่อ
ที่เจ๋งคือ EXCEPT ทำให้หาข้อมูลที่ “ขาดหาย” ได้ง่าย เช่น รายชื่อสินค้าที่ไม่เคยขาย รายชื่อลูกค้าที่ไม่มีธุรกรรมในปีนี้ หรือเอกสารที่รออนุมัติ ทั้งหมดเหล่านี้เป็นการลบชุดข้อมูลออก มันจะช่วยเวลาหาข้อมูลที่หายไป
ส่วนตัวผมชอบใช้ EXCEPT เมื่อต้องการตรวจสอบ “ความสมบูรณ์” ของข้อมูล เช่น มีสินค้ากี่ชิ้นที่ยังไม่เคยขาย ลูกค้าที่ลืมทำการขายไป การใช้ EXCEPT + COUNTROWS ช่วยให้รู้ว่าขาดไปเท่าไหร่