COUNTROWS เป็นฟังก์ชันการรวม (Aggregation) ที่นับจำนวนแถวในตารางที่ระบุ ไม่ว่าจะเป็นตารางจริงในโมเดลหรือตารางเสมือน (Virtual Table) จากฟังก์ชันอื่นๆ เช่น FILTER, VALUES, DISTINCT นับเท่าไหร่? ผลลัพธ์ก็คือจำนวนแถวเต็ม ๆ
| อาร์กิวเมนต์ | ชนิด | คำอธิบาย |
|---|---|---|
| table | table | ตารางที่ต้องการนับจำนวนแถว อาจเป็นตารางจริง (Sales, Customers) หรือตารางเสมือนจากฟังก์ชัน (FILTER, VALUES, DISTINCT, GENERATE) |
COUNTROWS ใช้นับจำนวนแถวในตาราง โดยไม่สนใจว่าแถวนั้นมีค่าอะไรอยู่ นั่นคือ ‘แถว’ กับ ‘ค่าในแถว’ คนละเรื่องกัน
ที่เจ๋งคือ COUNTROWS ทำงานได้ดีกับทุกสถานการณ์: ตารางจริง (Sales, Customers) หรือตารางเสมือนจากฟังก์ชันทำการ Filter (FILTER, VALUES, DISTINCT) บริบท Filter Context ก็ถูกพิจารณาโดยอัตโนมัติ ถ้ามีการสลักตัวกรองจากหน้าจออยู่ COUNTROWS ก็นับเฉพาะแถวที่ผ่านตัวกรองเหลือเท่านั้น
ส่วนตัวผมว่า COUNTROWS คือ ‘ความจริงใจ’ ของการนับในDAX – มันนับแล้วจบ ไม่มีเล่นเกม ไม่มี BLANK ขาด ขาดก็ขาด 😎
ใช้ COUNTROWS ครอบตารางที่ได้จาก FILTER เพื่อวัดจำนวนรายการที่ผ่านเงื่อนไข
ใช้ COUNTROWS(VALUES(Column)) เพื่อนับจำนวนค่าที่ไม่ซ้ำในบริบทปัจจุบัน โดยสามารถต่อยอดด้วยการกรองตารางก่อนนับได้
ถ้าตาราง Sales มี 2,452 แถว จะคืนค่า 2,452 ถ้ามีการเลือก 'Region = North' จากหน้าจอ ก็นับเฉพาะแถวใน Sales ที่เป็น Region North เท่านั้น COUNTROWS ศึกษา Filter Context โดยอัตโนมัติ
FILTER สร้างตารางเสมือนของแถว Sales ที่ Amount > 5,000 จากนั้น COUNTROWS นับจำนวนแถวของตารางเสมือนนั้น ผลลัพธ์คือจำนวน Order ที่มียอดเงินมากกว่า 5,000 บาท
VALUES สร้างตารางเสมือนของ CustomerID ที่ไม่ซ้ำ COUNTROWS นับแถวของตารางนั้น ผลลัพธ์คือจำนวนลูกค้าที่ไม่ซ้ำ นี่คือวิธี COUNTROWS + VALUES = DISTINCTCOUNT แต่ยืดหยุ่นมากขึ้น
ตัวอย่างที่ซับซ้อนขึ้น: ก่อนอื่นกรอง Sales ให้เหลือเฉพาะแถวที่ Amount มากกว่าค่าเฉลี่ยทั้งหมด จากนั้นใช้ SELECTCOLUMNS เพื่อเลือกเฉพาะคอลัมน์ CustomerID แล้ว VALUES เพื่อให้ได้ค่า Unique ของ CustomerID สุดท้าย COUNTROWS นับจำนวนลูกค้าที่ไม่ซ้ำในกลุ่มคำสั่งขนาดใหญ่ นี่คือการรวมกำลัง Filter + SELECTCOLUMNS + VALUES + COUNTROWS
Microsoft Best Practice: ใช้ COUNTROWS แทน COUNT เสมอ COUNTROWS นับแถว (Rows) ทั้งหมด COUNT นับเฉพาะค่าตัวเลขที่ไม่ใช่ BLANK จึงข้ามแถวที่มี BLANK ไป ใช้ COUNT เฉพาะเมื่อต้องการยกเว้น BLANK โดยเฉพาะ หรือต้องการนับค่าตัวเลขในคอลัมน์ COUNTROWS ที่นอกจากเร็วกว่า ยังให้ผลถูกต้องที่สุด
เพราะว่า VALUES รวมค่า BLANK เข้ามาด้วย ถ้าคอลัมน์มี BLANK จริง ๆ VALUES จะคืนค่า BLANK เป็นแถวหนึ่ง จากนั้น COUNTROWS ก็นับ BLANK แถวนั้นด้วย หากต้องการหลีกเลี่ยงให้กรอง BLANK ออกด้วย FILTER: COUNTROWS(FILTER(VALUES(Column), NOT(ISBLANK(Column))))
COUNTROWS นับแถว COUNTA นับเซลล์ที่ไม่ใช่ BLANK ใน 'คอลัมน์' COUNTAX คือ iterator (วนลูป) นับแล้ว evaluate expression ในแต่ละแถว ส่วนใหญ่ใช้ COUNTROWS เพราะเร็วและชัดเจน COUNTAX ใช้เมื่อต้องนับแบบมีเงื่อนไขเชิงซับซ้อน
ส่ง BLANK (ไม่ใช่ 0) ถ้าตารางไม่มีแถวเลย COUNTROWS(FILTER(Sales, Sales[Amount] > 1000000)) ถ้าไม่มี Order ที่มากกว่า 1 ล้าน ผลลัพธ์คือ BLANK ไม่ใช่ 0 ที่สำคัญ: BLANK ≠ 0 ให้ระวัง
ฟังก์ชันที่ผู้เขียนโยงไว้กับ COUNTROWS จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง
APPROXIMATEDISTINCTCOUNT คืนจำนวนค่าไม่ซ้ำแบบประมาณเพื่อความเร็ว เหมาะกับข้อมูลขนาดใหญ่และงาน DirectQuery ในแหล่งข้อมูลที่รองรับ เมื่อความแม่นยำ 100% ไม่จำเป็น
COUNT นับจำนวนแถวที่คอลัมน์มีค่าไม่ว่าง (non-blank) รองรับตัวเลข วันที่ และข้อความ แต่ไม่นับ Boolean ทำงานภายใต้ filter context และเกิด context transition เมื่อใช้ใน row context เหมาะสำหรับนับรายการที่มีข้อมูลในคอลัมน์เฉพาะ แต่ควรใช้ COUNTROWS แทนเมื่อนับแถวทั้งหมด
COUNTA นับจำนวนเซลล์ที่มีค่าไม่ว่าง (non-blank) ในคอลัมน์ โดยรวมตัวเลข ข้อความ วันที่ และค่าตรรกะ ต่างจาก COUNT ที่นับเฉพาะตัวเลขเท่านั้น
COUNTAX ประเมินนิพจน์ต่อแถวในตาราง แล้วนับจำนวนผลลัพธ์ที่ไม่ว่าง เหมาะกับการนับค่าที่อาจเป็นข้อความ ตรรกะ หรือนิพจน์ที่ซับซ้อน ไม่ใช่แค่ตัวเลข
COUNTBLANK นับจำนวนค่า BLANK ในคอลัมน์ ช่วยวัดความครบถ้วนของข้อมูลและตรวจสอบคุณภาพข้อมูลภายใต้บริบทตัวกรองปัจจุบัน
DISTINCTCOUNT นับจำนวนค่าที่แตกต่างกันทั้งหมดในคอลัมน์ รวมถึง BLANK values ถ้าไม่มีแถวข้อมูล จะคืนค่า BLANK
ALL มีพฤติกรรมแตกต่างกัน 2 แบบ: ใช้เป็น Table Expression จะคืนทุกแถวในตาราง หรือทุกค่าในคอลัมน์ โดยไม่สนใจ Filter ใดๆ เหมาะสำหรับใช้ร่วมกับ FILTER, COUNTROWS, SUMMARIZE หรือใช้เป็น CALCULATE Modifier เพื่อลบ Filter ออกจากตารางหรือคอลัมน์ที่ระบุ ทำให้สามารถคำนวณ Grand Total หรือหาเปอร์เซ็นต์เทียบกับยอดรวมได้
ALLEXCEPT ใช้สำหรับ “ล้างตัวกรองเกือบทั้งหมด” โดยคงตัวกรองไว้เฉพาะคอลัมน์ที่ระบุ เหมาะกับการคำนวณ Sub-total/สัดส่วนภายในกลุ่ม เช่น ยอดขายต่อหมวดหมู่ โดยไม่สนตัวกรองอื่น ๆ แนวคิดหลักคือ ลบตัวกรองของตาราง แล้วคงตัวกรองของคอลัมน์ที่เลือกไว้
ALLNOBLANKROW ทำงานคล้าย ALL แต่มีจุดเด่นคือ “ตัดแถวว่าง” ที่ระบบสร้างขึ้นอัตโนมัติเมื่อข้อมูลหลุดความสัมพันธ์ เช่น คีย์ในตารางข้อเท็จจริงไม่พบในตารางมิติ จึงเหมาะกับการคำนวณยอดรวม/สัดส่วนที่ไม่ต้องการให้แถวว่างเข้ามาปนผลลัพธ์ และยังใช้เป็นตัวช่วยตรวจจับปัญหาคุณภาพข้อมูลในโมเดลได้ด้วย
FILTER ใช้กรองแถวในตารางตามเงื่อนไขที่ซับซ้อน โดยวนลูปทุกแถวและประเมินเงื่อนไข เหมาะกับการกรองด้วย Measure หรือ Expression ซึ่ง Boolean Expression ทำไม่ได้ แต่ต้องระวังเรื่อง Performance เพราะเป็น Iterator Function ที่ช้ากว่า Boolean Expression ดังนั้นควรใช้เฉพาะเมื่อจำเป็น และอย่าใช้ FILTER กับ RELATED เพื่อกรองข้ามตาราง ให้กรองที่ Dimension Table โดยตรงแทน
DISTINCT คืนค่าตารางที่มีคอลัมน์เดียว ซึ่งประกอบด้วยค่าที่ไม่ซ้ำกันจากคอลัมน์ที่ระบุ โดยไม่รวม Blank Row ที่เกิดจาก Invalid Relationship ความแตกต่างหลักจาก VALUES คือ DISTINCT จะซ่อน Data Quality Issues ในขณะที่ VALUES จะเตือนให้เห็น
GROUPBY สร้างตารางสรุปโดยจัดกลุ่มตามคอลัมน์ที่กำหนด และเพิ่มคอลัมน์คำนวณแบบกลุ่มต่อกลุ่มได้ โดยใช้ CURRENTGROUP() เข้าถึงแถวภายในกลุ่ม เหมาะกับการคำนวณซ้อนหรือคำนวณจากคอลัมน์ชั่วคราว (local columns)
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 ดีกว่าอย่างมาก
VALUES ดึงค่าที่ไม่ซ้ำจากคอลัมน์ หรือดึงแถวทั้งหมดจากตาราง โดยรวมแถว BLANK ที่เกิดจากข้อผิดพลาดของความสัมพันธ์ (Referential Integrity Violations) ส่วน DISTINCT จะไม่รวมแถว BLANK นี้
HASONEVALUE ตรวจสอบว่า Column ที่ผ่านการ Filter มีเพียงค่าเดียวเท่านั้น Return TRUE หากตรงตามเงื่อนไข FALSE หากไม่ใช่ ใช้หลักเพื่อสร้าง Measure ที่ "ฉลาด" ตามการเลือก Filter ของผู้ใช้
Comments
อีเมลของคุณจะไม่ถูกเผยแพร่