ในซีรีส์ Power BI บทก่อนหน้านี้เราได้เรียนรู้จักสูตร DAX พื้นฐานกันไปแล้ว คราวนี้เรามารู้จักฟังก์ชันกลุ่ม Table Function เพิ่มเติม นั่นก็คือ FILTER, DISTINCT, VALUES, ALL ซึ่งจะช่วยให้เราสามารถเขียนสูตร DAX ที่ซับซ้อนได้มากขึ้นในอนาคตนั่นเอง
แต่เพื่อไม่ให้มันเยอะเกินไป เดี๋ยวบทความนี้ผมจะพูดถึง FILTER แค่ตัวเดียวก่อน ส่วน ALL, DISTINCT, VALUES และผองเพื่อน จะพูดในตอนถัดไปนะครับ
สารบัญ
ไฟล์ประกอบ
ใช้ไฟล์เดิมที่ทำมาจากตอนก่อนหน้าได้เลยนะครับ หรือจะใช้อันนี้ก็ได้
Table Function คืออะไร?
คำว่า Table Function ก็คือ ฟังก์ชันที่ให้ผลลัพธ์กลับมาเป็น Table หรือตารางนั่นเอง ต้องบอกว่าฟังก์ชันปกติที่เราคุ้นเคยกันก่อนหน้านี้ทุกอัน จะให้คำตอบออกมาเป็นค่าเดียว (เรียกว่า Scalar Value) ไม่ว่าจะเป็นประเภทตัวเลข ตัวหนังสือ logic ก็ตาม ก็จะมีค่าเดียวมาโดยตลอด
แต่เจ้า Table Function ไม่ใช่แบบนั้น มันดันให้ผลลัพธ์กลับมาเป็นตารางเลย เรามาทำความรู้จักมันทีละตัวกันครับ
FILTER
ซึ่งตัวที่น่าจะเห็นหน้าตาเป็นตารางได้ชัดเจนที่สุดก็คือ เจ้า FILTER นี่แหละ เพราะมันจะให้ผลลัพธ์เป็นตารางที่ผ่านการคัดกรองจนเหลือสิ่งที่ต้องการแล้วนั่นเอง (คล้ายๆ กับ FILTER ซึ่งเป็นฟังก์ชันของ Excel 365 เลยเนอะ แต่มันเป็นคนละตัวกันนะครับ อันที่สอนในบทความนี้คือใน DAX)
วิธีการใช้งานคือ
FILTER ( <Table>, <FilterExpression> )
โดยที่ <Table> ก็คือตาราง Original ซึ่งจะเป็นแค่การใส่ชื่อตารางธรรมดาๆ หรือ เป็น Table Function ตัวอื่นก็ยังได้
ส่วน <FilterExpression> ก็คือเงื่อนไขในการคัดกรอง โดยมันจะต้องเขียนสูตรส่วนนี้ให้ได้ผลลัพธ์เป็น TRUE/FALSE เพื่อคัดกรองเอาเฉพาะตัวที่เป็น TRUE มาแสดง
สมมติว่า ผมอยากจะ Filter ตาราง dProduct ด้วยสูตร ผมสามารถใช้ฟังก์ชัน FILTER นี้ได้เลย และเพื่อให้เห็นผลลัพธ์ชัดเจนที่สุด ผมจะใช้คำสั่ง New Table เพื่อให้มันออกมาเป็นตารางอีกอันนึงชัดๆ เลย
ผมใส่สูตรว่า
myTable = FILTER(dProduct,dProduct[UnitPrice]>200)
แปลว่า ผมเอาตาราง dProduct มา Filter นะ โดยเงื่อนไขคือ dProduct[UnitPrice]>200 ซึ่งแปลว่า คอลัมน์ UnitPrice มีค่ามากกว่า 200 นั่นเอง
ซึ่งผลลัพธ์ก็จะออกมาเป็น Table ที่มีจำนวนคอลัมน์เท่ากับ dProduct ทุกประการ แค่มีจำนวนแถวลดลง เพราะมีการคัดกรองตามเงื่อนไขใน <FilterExpression>
ปล. Power BI มีอัปเดทหน้าตา UI ใหม่นิดหน่อยนะ (ให้เหมือน Ribbon ใน Excel มากขึ้น) หน้าตาเลยแปลกไปจากบทความก่อน
การอ้างอิงคอลัมน์ที่จะ FILTER
<FilterExpression> ของ FILTER เนี่ยปกติจะสามารถอ้างอิงคอลัมน์ได้เฉพาะจาก Field ที่อยู่ใน <Table> ที่อ้างถึงเท่านั้น แต่ถ้าอยากจะอ้างอิงข้ามตารางต้องใช้ RELATED มาช่วยนะครับ
ตัวอย่างการใช้ RELATED ใน FILTER
หากเราต้องการ Filter fSales ให้เหลือรายการเฉพาะที่มาจากช่องทาง online เท่านั้น แม้ว่าจะไม่มี StoreType ให้เลือกในตารางนี้ตรงๆ เราก็ใช้ RELATED ดึงมามาช่วยได้ครับ
OnlinefSales = FILTER(fSales,RELATED(dStores[StoreType])="online")
แล้วถ้าจะใส่เงื่อนไขมากกว่า 1 อย่างล่ะ?
ถ้าสังเกตดูจะเห็นว่า input ที่เป็นเงื่อนไขของ FILTER นั้นมีแค่ตัวเดียว แปลว่าเราไม่สามารถคั่นด้วยเครื่องหมาย , ได้แบบ SUMIFS นะ แปลว่าเราจะต้องใช้เงื่อนไขแบบ AND OR มาช่วยแทนนั่นเอง
เงื่อนไขแบบ AND
สามารถใช้ฟังก์ชัน AND(เงื่อนไข1,เงื่อนไข2) ได้ แต่ก็จะได้แค่ 2 เงื่อนไขนี่แหละ
myTable = FILTER(dProduct,
AND(dProduct[UnitPrice]>200,dProduct[BrandName]="Litware"))
แปลว่าเอาที่ Unit Price > 200 และ ฺBrandName เป็น Litware
ถ้าจะใช้มากกว่านี้ให้ใช้เครื่องหมาย && มาช่วยแทน
เช่น เงื่อนไข1 && เงื่อนไข2 && เงื่อนไข3
myTable = FILTER(dProduct,
dProduct[UnitPrice]>200 && dProduct[BrandName]="Litware" && dProduct[ClassName]="Deluxe")
แปลว่าเอาที่ Unit Price > 200 และ ฺBrandName เป็น Litware และ ClassName เป็น Deluxe
Tips : ถ้าอยากจะเขียน FILTER ซ้อนไปอีกชั้น เพื่อทำเงื่อนไขซ้อนกันแบบ AND ก็ย่อมได้นะ เพราะซ้อนไปเรื่อยๆ ก็แปลว่าต้องผ่านทุกเงื่อนไขนั่นแหละ จึงเป็น AND โดยปริยาย แต่ผมว่ามันอ่านยากเปล่าๆ อย่าทำเลย
เงื่อนไขแบบ OR
สามารถใช้ฟังก์ชัน OR(เงื่อนไข1,เงื่อนไข2) ได้ แต่ก็จะได้แค่ 2 เงื่อนไขเช่นกัน
myTable = FILTER(dProduct,
OR(dProduct[UnitPrice]>1000, dProduct[BrandName]="Litware"))
แปลว่าเอาที่ Unit Price > 1000 หรือ BrandName เป็น Litware
ถ้าจะใช้มากกว่านี้ให้ใช้เครื่อบหมาย || มาช่วยแทน
เช่น เงื่อนไข1 || เงื่อนไข2 || เงื่อนไข3
myTable = FILTER(dProduct,dProduct[UnitPrice]>1000 || dProduct[BrandName]="Litware" || dProduct[BrandName]="Proseware")
แปลว่าเอาที่ Unit Price > 1000 หรือ BrandName เป็น Litware หรือ Proseware
แต่ถ้ากรณีจะอ้างอิงค่าใน Field เดียวกันหลายๆ item อย่าง Litware กับ Proseware เราไม่ต้องใช้ OR ก็ได้ แต่หันมาใช้การอ้างอิงเงื่อนไขแบบ field IN {item1, item2} แทนจะง่ายกว่าการเขียนว่า field = item1 ||field = item2 เช่น
myTable = FILTER(dProduct,dProduct[UnitPrice]>1000 || dProduct[BrandName] IN {"Litware" , "Proseware"} )
จะได้ผลลัพธ์เหมือนกันทุกประการเลยครับ
ตัวอย่างทั้งหมดที่ผ่านมายังเป็นการใช้งานพื้นฐานแบบให้เห็นภาพชัดๆ คือลองสร้าง New Table ขึ้นมาเลย แต่ในความเป็นจริงเราสามารถเอา FILTER ไปประกอบกับสูตรอื่นๆ ที่ต้องการ input เป็น Table ได้อีกนะครับ เช่น สร้าง Measure ยอดขายเฉพาะยอดแบบ Online เท่านั้น
ตัวอย่างการใช้ FILTER ใน Measure
ผมลองสร้าง New Measure ตัวใหม่ ที่สูตรเหมือน TotalRevenue ทุกอย่าง แค่ส่วนของ Table ใน SUMX เราใช้ FILTER สร้างตารางจำลองขึ้นมาให้เหลือเฉพาะ Transaction ที่มาจากช่องทาง Online เท่านั้น เพื่อที่ผลลัพธ์มันจะได้เอาจำนวน SalesQuantity * UnitPrice เฉพาะ Row ที่มาจากช่องทางออนไลน์ไง
TotalRevenue = SUMX(fSales,fSales[SalesQuantity]*RELATED(dProduct[UnitPrice]))
TotalOnlineRevenue = SUMX(FILTER(fSales,RELATED(dStores[StoreType])="Online"),
fSales[SalesQuantity]*RELATED(dProduct[UnitPrice]))
พอเรามี Measure 2 ตัวแล้ว เราก็สามารถสร้าง %Portion ที่น่าสนใจได้ เช่น
และนี่ก็เป็นตัวอย่างการใช้ FILTER ครับ เดี๋ยวบทความหน้าเรามาต่อกันที่ ALL, DISTINCT, VALUES และผองเพื่อนกันครับ รับรองว่าลึกซึ้งขึ้นไปอีกครับ
ทั้งหมดนี้ เพื่อปูทางไปสู่ฟังก์ชันที่ลึกซึ้งที่สุดอันนึงใน DAX นั่นก็คือ CALCULATE ครับ!!
สารบัญ Series Power BI
- POWER BI ตอนที่ 01: POWER BI คืออะไร?
- POWER BI ตอนที่ 02: พื้นฐาน EXCEL ที่สำคัญก่อนจะเรียนรู้ POWER BI
- POWER BI ตอนที่ 03: ภาพรวมการใช้งาน POWER BI DESKTOP
- POWER BI ตอนที่ 04: สร้าง REPORT แรก ใน POWER BI
- POWER BI ตอนที่ 05: วิธีการ DRILL เพื่อเจาะลึกข้อมูลใน REPORT
- POWER BI ตอนที่ 06: การปรับแต่งสีใน VISUAL ด้วย CONDITIONAL FORMAT
- POWER BI ตอนที่ 07: เริ่ม GET DATA ตั้งแต่ไฟล์ยังว่างเปล่า
- POWER BI ตอนที่ 08: สร้าง DATA MODEL ที่เหมาะสม
- POWER BI ตอนที่ 09: สร้าง DATE TABLE ด้วย DAX
- POWER BI ตอนที่ 10: เรียนรู้ DAX เบื้องต้น
- POWER BI ตอนที่ 11: เรียนรู้ DAX Table Function – FILTER
- POWER BI ตอนที่ 12: DISTINCT, VALUES, ALL และผองเพื่อน
- POWER BI ตอนที่ 13: CALCULATE ฟังก์ชันที่ทรงพลังที่สุดใน DAX
- Power BI ตอนที่ 14: Context Transition และ พลังแฝงใน Measure
- Power BI ตอนที่ 15: วิธีดึงค่าจาก Slicer มาคำนวณใน Report
- Power BI ตอนที่ 16 : เดินทางข้ามเวลาไปกับ Time Intelligence DAX Function
- Power BI ตอนที่ 17 : วิธีทำรายงานเทียบเป้าหมาย Target vs Actual
- Power BI ตอนที่ 18 : วิธีการกระจายเป้า Allocate Target ด้วย DAX
- Power BI ตอนที่ 19 : การปรับ Cross Filter Direction เพื่อคำนวณค่าในตาราง Dimension
- ส่วนเสริม
- การคำนวณต้นทุนแบบ FIFO ด้วย DAX
- แสดงข้อมูลสรุปแบบ Top N + Others (ฉบับเทพเอ็กเซล)
- การวิเคราะห์ Event ที่มีช่วงเวลาเริ่มต้นกับสิ้นสุดคนละวัน
- เปรียบเทียบ MAX vs LASTDATE ในภาษา DAX
ใครสนใจอยากเรียนเป็นคลิปวีดีโอ ผมมี