GENERATEALL วนแถวของตาราง 1 แล้วสร้าง Cartesian product กับผลลัพธ์ของตาราง 2 โดยคงแถวที่ไม่มีข้อมูลย่อย ต่างจาก GENERATE ตรงที่ไม่ตัดแถวหลักออก
| อาร์กิวเมนต์ | ชนิด | คำอธิบาย |
|---|---|---|
| table1 | table | ตารางหลักที่จะวนแถวทีละแถว ต้องเป็นนิพจน์ DAX ที่คืนตาราง |
| table2 | table | นิพจน์ตารางที่ประเมินแยกต่อแถวของ table1 ใน row context ของแถวปัจจุบัน อาจคืนผลว่าง (ไม่มีแถว) แต่จะถูกเก็บไว้ในผลลัพธ์ final |
GENERATEALL คือฟังก์ชันสำคัญในเมื่อต้องการรวมตารางสองตารางแบบ outer apply ทำงานโดยวนแถวของ Table1 ทีละแถว แล้วประเมิน Table2 ในบริบทของแถวนั้น สร้าง Cartesian product จากผลลัพธ์ และสำคัญตรงนี้ – ถ้า Table2 ให้ผลว่างสำหรับแถวใดแถวหนึ่ง แถวนั้นจะถูกเก็บไว้ในผลลัพธ์พร้อม null values สำหรับคอลัมน์ของ Table2
ที่เจ๋งคือการทำงานแบบ outer apply นี้มีประโยชน์มากสำหรับการหา records ที่ไม่มี match ในตารางที่สอง เช่น สินค้าที่ไม่มีรายการขาย หรือลูกค้าที่ไม่มีธุรกรรม ถ้าใช้ GENERATE ธรรมดา มันจะตัดแถวเหล่านั้นออกไป แต่ GENERATEALL เก็บไว้เพื่อให้คุณเห็นความครอบคลุมที่แท้จริง
ส่วนตัวผมใช้ GENERATEALL เวลาต้องการ audit หรือ gap analysis – หาว่าสินค้าไหนขายไม่ออก ลูกค้าไหนไม่ซื้อ หรือคู่ region-product ไหนไม่มีข้อมูล ทำให้รายงานครบถ้วนและเห็นจุดที่ควรปรับปรุง
เหมาะกับงานตรวจสอบ/การวิเคราะห์ที่ไม่อยากให้แถวหายไปเมื่อไม่มีข้อมูลย่อย
เช่น ตรวจว่ารายการไหนไม่มีข้อมูลย่อย
ใช้ GENERATEALL กับ FILTER เพื่อขยายแต่ละสินค้าไปกับรายการขายที่ตรงกัน ถ้าสินค้าไม่มีขายเลย GENERATEALL ยังคงให้ผลลัพธ์ 1 แถวของสินค้านั้นโดยมี null columns สำหรับ Sales ช่วยให้เห็นสินค้าใดขายไม่ออก
GENERATE และ GENERATEALL มี syntax เหมือนกัน แต่ถ้า FILTER ไม่มีแถวสำหรับสินค้าใด GENERATE จะไม่รวมสินค้านั้นในผลลัพธ์ ส่วน GENERATEALL จะรวมไว้ คำเลือกขึ้นอยู่ว่าต้องการเห็นแถวว่างหรือไม่
สร้างชุดวันที่สำหรับแต่ละ order date ถึง 31 Dec 2025 แม้บางวันไม่มีข้อมูลธุรกรรม GENERATEALL เก็บไว้ ใช้สำหรับสร้างรายงาน timeline หรือ Gantt chart
ขั้นแรก สร้าง ProductsSummary ด้วย ADDCOLUMNS บวกจำนวนขายต่อสินค้า แล้ว GENERATEALL ใช้ IF เพื่อตัดสินใจว่าประเมิน FILTER หรือ BLANK ตามจำนวนขาย ตัวอย่างนี้แสดงการ combine logic ซับซ้อนในลำดับชั้น table generation
เวลา table2 ให้ผลว่าง (ไม่มีแถว) สำหรับบางแถวของ table1 GENERATE ตัดแถวเหล่านั้นออก แต่ GENERATEALL เก็บไว้พร้อม null values ที่เหมาะสำหรับการตรวจสอบครบถ้วน
ได้ ผม มักใช้ GENERATEALL รวมกับ COUNTROWS หรือ COALESCE เพื่อตรวจว่าแถวไหนไม่มีข้อมูลจาก table2 ลองแล้วจะเห็นความ valuable ในการ audit
CROSSJOIN สร้าง Cartesian product ธรรมชาติ (ทุกคู่) GENERATEALL วนแถว table1 แล้วประเมิน table2 ต่อแถว ซึ่ง table2 อาจขึ้นกับบริบท (row context) ของ table1 GENERATEALL เหมาะกว่าเมื่อต้องการ conditional logic
ผมเจอบ่อยที่สุดคือ hierarchical expand – เช่น Region-Product matrix ต้องเห็นคู่ไหนไม่มี data ถ้าใช้ GENERATE มันตัดคู่เหล่านั้นออก แต่ GENERATEALL เก็บไว้เพื่อให้รายงาน audit ครบถ้วน
ฟังก์ชันที่ผู้เขียนโยงไว้กับ GENERATEALL จัดกลุ่มตามหมวด · ชี้ที่ชื่อใดชื่อหนึ่ง แล้วฟังก์ชันที่ใช้คู่กันจะมีจุดทอง
ADDCOLUMNS เป็นฟังก์ชัน table transformation ที่ใช้สำหรับเพิ่มคอลัมน์ใหม่ (Calculated Columns) เข้าไปในตารางที่มีอยู่เดิม โดยคำนวณค่าในแต่ละแถวผ่าน Row Context และส่งคืนตารางเดิมพร้อมคอลัมน์ใหม่ต่อท้าย
CROSSJOIN สร้างตารางใหม่โดยการรวมแถวทั้งหมดจากตารางที่ระบุ โดยสร้างทุก Combination ที่เป็นไปได้ ผลลัพธ์คือตารางที่มีจำนวนแถวเท่ากับผลคูณของจำนวนแถวของแต่ละตาราง
GENERATE วนทีละแถวใน Table1 แล้วประเมิน Table2 ในบริบทของแถวนั้น (row context) จากนั้นรวมผลทั้งหมดเป็นตารางเดียว ถ้า Table2 ว่างเปล่าในรอบไหน แถวนั้นจาก Table1 จะถูกตัดออก (ต่างจาก GENERATEALL)
GENERATESERIES สร้างตารางคอลัมน์เดียวที่เป็นลำดับตัวเลขจาก StartValue ถึง EndValue ด้วย increment ที่กำหนดได้ เหมาะกับตารางช่วย parameter table หรือสร้างชุดตัวเลขสำหรับ what-if analysis
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 ดีกว่าอย่างมาก
FILTER ใช้กรองแถวในตารางตามเงื่อนไขที่ซับซ้อน โดยวนลูปทุกแถวและประเมินเงื่อนไข เหมาะกับการกรองด้วย Measure หรือ Expression ซึ่ง Boolean Expression ทำไม่ได้ แต่ต้องระวังเรื่อง Performance เพราะเป็น Iterator Function ที่ช้ากว่า Boolean Expression ดังนั้นควรใช้เฉพาะเมื่อจำเป็น และอย่าใช้ FILTER กับ RELATED เพื่อกรองข้ามตาราง ให้กรองที่ Dimension Table โดยตรงแทน
ยังไม่มีบทความที่เกี่ยวข้องกับฟังก์ชันนี้
Comments
อีเมลของคุณจะไม่ถูกเผยแพร่