🎯 Mục tiêu bài học
Sau bài học này, bạn sẽ:
✅ Hiểu Measures vs Calculated Columns
✅ Filter Context — khái niệm quan trọng nhất của DAX
✅ CALCULATE, ALL, FILTER — core functions
✅ Common DAX patterns: KPIs, Ranking, Running Total
✅ Time Intelligence: YoY, YTD, MTD, Moving Average
Thời gian: 45 phút | Độ khó: Intermediate-Advanced | Tool: Power BI Desktop
📖 Bảng Thuật Ngữ Quan Trọng
| Thuật ngữ | Tiếng Việt | Mô tả |
|---|---|---|
| DAX | Data Analysis Expressions | Formula language của Power BI |
| Measure | Phép đo | Aggregation tính at runtime |
| Calculated Column | Cột tính toán | Row-by-row, stored in model |
| Filter Context | Ngữ cảnh lọc | Tất cả filters active cho 1 cell |
| CALCULATE | Hàm CALCULATE | Thay đổi filter context |
| ALL | Hàm ALL | Remove filters từ table/column |
| FILTER | Hàm FILTER | Row-by-row filter table |
| Time Intelligence | Tính toán thời gian | YoY, YTD, MTD, Moving Average |
| RANKX | Hàm xếp hạng | Rank theo measure |
| SWITCH | Hàm chuyển đổi | Clean alternative cho nested IFs |
Checkpoint
Measure = runtime aggregation. Filter Context = all active filters cho 1 cell. CALCULATE = thay đổi context. ALL = remove filters. Đây là 4 pillars của DAX!
📐 1. DAX Basics
1.1 Measures vs Calculated Columns
| Measure | Calculated Column | |
|---|---|---|
| Tính khi nào | Runtime (mỗi khi viz đổi) | Load time (1 lần) |
| Stored | Không lưu trong data | Lưu trong bảng |
| Context aware | Thay đổi theo filter | Cố định per row |
| Use case | Aggregations, KPIs | Row-level classification |
| Performance | Better cho aggregations | Better cho row lookups |
1.2 Tạo Measure
1// New Measure (Modeling → New Measure)2Total Sales = SUM(Sales[Amount])1.3 Tạo Calculated Column
1// New Column (Modeling → New Column)2Profit Margin = Sales[Profit] / Sales[Revenue]3 4Customer Segment = 5 IF(Customer[TotalSpend] > 10000000, "VIP",6 IF(Customer[TotalSpend] > 5000000, "Premium",7 IF(Customer[TotalSpend] > 1000000, "Standard", "Basic")))Rule of thumb: Nếu cần aggregate → dùng Measure. Nếu cần classify row → dùng Calculated Column. 90% trường hợp nên dùng Measure!
Checkpoint
Measure = runtime + context-aware (dùng 90%). Calc Column = load time + fixed per row (classify). Tạo: Modeling → New Measure / New Column!
🔍 2. Filter Context
2.1 Hiểu Filter Context
12025 2026 Total2Electronics 50M 60M 110M ← filter: Category=Electronics3Furniture 30M 35M 65M ← filter: Category=Furniture4Total 80M 95M 175M ← no category filterMỗi cell có filter context khác nhau.
2.2 CALCULATE
1CALCULATE(expression, filter1, filter2, ...)2 3// Electronics Sales (always)4Electronics Sales = 5 CALCULATE(SUM(Sales[Amount]), Products[Category] = "Electronics")6 7// Last Year Sales8Last Year Sales = 9 CALCULATE(SUM(Sales[Amount]), DATEADD(DateTable[Date], -1, YEAR))2.3 ALL — Remove Filters
1// % of Grand Total2% of Total = 3 DIVIDE(4 SUM(Sales[Amount]),5 CALCULATE(SUM(Sales[Amount]), ALL(Sales))6 )2.4 FILTER
1// VIP Sales only2VIP Sales = 3 CALCULATE(4 SUM(Sales[Amount]),5 FILTER(Customer, Customer[Segment] = "VIP")6 )7 8// Large Orders9Large Orders = 10 CALCULATE(COUNTROWS(Sales), FILTER(Sales, Sales[Amount] > 1000000))CALCULATE là hàm quan trọng nhất trong DAX! Nó thay đổi filter context. Không hiểu CALCULATE = không hiểu DAX. Dành thời gian practice nhiều!
Checkpoint
Filter Context = tất cả filters active. CALCULATE = thay đổi context. ALL = remove filters (cho % of total). FILTER = row-by-row filtering. CALCULATE = #1 function in DAX!
📊 3. Common DAX Patterns
3.1 Basic KPIs
1Total Revenue = SUM(Sales[Revenue])2Total Profit = SUM(Sales[Profit])3Profit Margin = DIVIDE([Total Profit], [Total Revenue], 0)4Order Count = COUNTROWS(Sales)5AOV = DIVIDE([Total Revenue], [Order Count], 0)6Customer Count = DISTINCTCOUNT(Sales[CustomerID])3.2 Ranking
1Product Rank = 2 RANKX(ALL(Products[ProductName]), [Total Revenue], , DESC, Dense)3 4IsTopN = IF([Product Rank] <= 10, "Top 10", "Others")3.3 Running Total
1Cumulative Sales = 2 CALCULATE(3 [Total Revenue],4 FILTER(ALL(DateTable[Date]), DateTable[Date] <= MAX(DateTable[Date]))5 )3.4 Conditional Formatting
1Revenue Color = 2 IF([Revenue Growth %] >= 0.10, "#34a853",3 IF([Revenue Growth %] >= 0, "#fbbc04", "#ea4335"))Checkpoint
KPI measures: SUM, COUNTROWS, DISTINCTCOUNT, DIVIDE. RANKX = rank across table. Running Total = CALCULATE + FILTER(ALL(Date)). Luôn dùng DIVIDE thay vì /!
⏱️ 4. Time Intelligence
4.1 Date Table (Prerequisite)
1DateTable = 2 ADDCOLUMNS(3 CALENDARAUTO(),4 "Year", YEAR([Date]),5 "Month", MONTH([Date]),6 "MonthName", FORMAT([Date], "MMM"),7 "Quarter", "Q" & FORMAT([Date], "Q")8 )4.2 Year-over-Year
1PY Sales = CALCULATE([Total Revenue], DATEADD(DateTable[Date], -1, YEAR))2 3YoY Growth = DIVIDE([Total Revenue] - [PY Sales], [PY Sales], 0)4.3 YTD / MTD / QTD
1YTD Revenue = CALCULATE([Total Revenue], DATESYTD(DateTable[Date]))2MTD Revenue = CALCULATE([Total Revenue], DATESMTD(DateTable[Date]))3QTD Revenue = CALCULATE([Total Revenue], DATESQTD(DateTable[Date]))4.4 Previous Period & Moving Average
1PM Revenue = CALCULATE([Total Revenue], DATEADD(DateTable[Date], -1, MONTH))2 3SPLY Revenue = CALCULATE([Total Revenue], SAMEPERIODLASTYEAR(DateTable[Date]))4 5MA3 Revenue = 6 AVERAGEX(7 DATESINPERIOD(DateTable[Date], MAX(DateTable[Date]), -3, MONTH),8 [Total Revenue]9 )Time Intelligence yêu cầu Date Table — continuous dates, no gaps. Dùng CALENDARAUTO() hoặc CALENDAR(start, end) để tạo. Mark as Date Table trong Modeling tab!
Checkpoint
Date Table = prerequisite (continuous dates). YoY = DATEADD(-1, YEAR). YTD = DATESYTD. MTD = DATESMTD. SAMEPERIODLASTYEAR = same period last year. Moving Average = AVERAGEX + DATESINPERIOD!
🔄 5. SWITCH Pattern
1// Clean alternative to nested IFs2Month Sort = 3 SWITCH([MonthName],4 "Jan", 1, "Feb", 2, "Mar", 3, "Apr", 4,5 "May", 5, "Jun", 6, "Jul", 7, "Aug", 8,6 "Sep", 9, "Oct", 10, "Nov", 11, "Dec", 12, 0)7 8// Dynamic measure selection9Selected Measure = 10 SWITCH(11 SELECTEDVALUE(MetricSelector[Metric]),12 "Revenue", [Total Revenue],13 "Profit", [Total Profit],14 "Orders", [Order Count],15 [Total Revenue]16 )SWITCH thay thế nested IF/ELSEIF — clean hơn, dễ đọc hơn, dễ maintain hơn. Dùng SWITCH(TRUE(), ...) cho complex conditions!
Checkpoint
SWITCH = clean nested IFs. SWITCH(TRUE(), ...) cho complex conditions. SELECTEDVALUE + SWITCH = dynamic measure selector cho dashboard interactivity!
📋 Tổng kết
Kiến thức đã học
| Chủ đề | Nội dung chính | Tầm quan trọng |
|---|---|---|
| Basics | Measures vs Calc Columns | Foundation |
| Filter Context | CALCULATE, ALL, FILTER | Core — #1 concept |
| Patterns | KPIs, Ranking, Running Total | Practical |
| Time Intelligence | YoY, YTD, MTD, Moving Avg | Business critical |
| SWITCH | Clean conditional logic | Code quality |
5 DAX Rules:
- Measures cho aggregations, Columns cho row classification
- Filter Context — hiểu context là hiểu DAX
- CALCULATE — function quan trọng nhất
- ALL — remove filters, FILTER — thêm filters
- Time Intelligence — YoY, MTD, YTD, moving averages
Câu hỏi tự kiểm tra
- Measures và Calculated Columns khác nhau thế nào?
- Filter Context trong DAX là gì?
- CALCULATE là function quan trọng nhất vì sao?
- Time Intelligence cần Date Table được setup thế nào?
Bài tiếp theo: Power BI Visualizations — Custom visuals và formatting trong Power BI!
🎉 Tuyệt với! Bạn đã nắm vững DAX fundamentals!
Nhớ: Hiểu Filter Context = hiểu DAX. CALCULATE là chìa khóa để mở mọi cánh cửa!
