Dax
by kpbray
Writes DAX measures, calculated columns, and calculations for Power BI. Use for business logic, time intelligence, and analytical calculations.
Skill Details
Repository Files
5 files in this skill directory
name: dax description: "Writes DAX measures, calculated columns, and calculations for Power BI. Use for business logic, time intelligence, and analytical calculations."
DAX Skill
This skill helps write DAX measures, calculated columns, and calculations for Power BI semantic models.
When to Use This Skill
- Creating measures for business calculations
- Implementing time intelligence (YTD, MTD, PY comparisons)
- Writing filter context manipulations
- Building KPIs and scorecards
- Creating ranking and top N analyses
- Calculating percentages, ratios, and growth rates
DAX Formatting Standards
Follow SQLBI formatting conventions for readable, maintainable DAX:
Basic Structure
Measure Name =
VAR VariableName = Expression
VAR AnotherVariable = AnotherExpression
RETURN
Result
Indentation Rules
- Use 4 spaces for indentation (or consistent tabs)
- Each function argument on a new line for complex expressions
- Align operators vertically
Good Formatting Example
Total Sales =
VAR SalesAmount = SUM(Sales[Amount])
VAR ReturnAmount = SUM(Returns[Amount])
VAR NetSales = SalesAmount - ReturnAmount
RETURN
NetSales
Multi-line Function Formatting
Sales YTD =
CALCULATE(
[Total Sales],
DATESYTD(Date[Date])
)
Filtered Sales =
CALCULATE(
[Total Sales],
FILTER(
ALL(Products),
Products[Category] = "Electronics"
)
)
Core DAX Patterns
Aggregation Measures
/// Total of all sales amounts
Total Sales =
SUM(Sales[Sales Amount])
/// Count of distinct customers
Customer Count =
DISTINCTCOUNT(Sales[Customer ID])
/// Average order value
Average Order Value =
AVERAGE(Sales[Order Amount])
/// Maximum sale amount
Max Sale =
MAX(Sales[Sales Amount])
Safe Division
Always use DIVIDE() instead of the / operator:
/// Profit margin percentage
Profit Margin % =
VAR Revenue = SUM(Sales[Revenue])
VAR Profit = SUM(Sales[Profit])
RETURN
DIVIDE(Profit, Revenue, 0)
Percentage of Total
/// Sales as percentage of total
Sales % of Total =
VAR CurrentSales = [Total Sales]
VAR AllSales = CALCULATE([Total Sales], ALL(Sales))
RETURN
DIVIDE(CurrentSales, AllSales, 0)
Cumulative Total
/// Running total of sales
Cumulative Sales =
CALCULATE(
[Total Sales],
FILTER(
ALL(Date),
Date[Date] <= MAX(Date[Date])
)
)
Time Intelligence Patterns
Year-to-Date (YTD)
/// Year-to-date sales
Sales YTD =
CALCULATE(
[Total Sales],
DATESYTD(Date[Date])
)
Month-to-Date (MTD)
/// Month-to-date sales
Sales MTD =
CALCULATE(
[Total Sales],
DATESMTD(Date[Date])
)
Quarter-to-Date (QTD)
/// Quarter-to-date sales
Sales QTD =
CALCULATE(
[Total Sales],
DATESQTD(Date[Date])
)
Prior Year (PY)
/// Sales from same period last year
Sales PY =
CALCULATE(
[Total Sales],
SAMEPERIODLASTYEAR(Date[Date])
)
Year-over-Year Growth
/// Year-over-year growth percentage
Sales YoY % =
VAR CurrentSales = [Total Sales]
VAR PriorYearSales = [Sales PY]
RETURN
DIVIDE(
CurrentSales - PriorYearSales,
PriorYearSales,
BLANK()
)
Prior Year YTD
/// Year-to-date sales from last year
Sales PYTD =
CALCULATE(
[Total Sales],
SAMEPERIODLASTYEAR(Date[Date]),
DATESYTD(Date[Date])
)
Moving Average
/// 3-month moving average
Sales 3M Avg =
AVERAGEX(
DATESINPERIOD(
Date[Date],
MAX(Date[Date]),
-3,
MONTH
),
[Total Sales]
)
Filter Context Manipulation
CALCULATE Basics
/// Sales for Electronics category only
Electronics Sales =
CALCULATE(
[Total Sales],
Products[Category] = "Electronics"
)
Remove Filters with ALL
/// Sales ignoring all filters
Total Sales All =
CALCULATE(
[Total Sales],
ALL(Sales)
)
Remove Specific Filters
/// Sales ignoring product filter only
Sales All Products =
CALCULATE(
[Total Sales],
REMOVEFILTERS(Products)
)
Keep Specific Filters with ALLEXCEPT
/// Percentage within category
% of Category =
VAR CurrentSales = [Total Sales]
VAR CategorySales =
CALCULATE(
[Total Sales],
ALLEXCEPT(Products, Products[Category])
)
RETURN
DIVIDE(CurrentSales, CategorySales, 0)
Iterator Functions
SUMX
/// Extended price (quantity * unit price)
Extended Price =
SUMX(
Sales,
Sales[Quantity] * Sales[Unit Price]
)
AVERAGEX
/// Average sales per customer
Avg Sales per Customer =
AVERAGEX(
VALUES(Customers[Customer ID]),
[Total Sales]
)
RANKX
/// Product rank by sales
Product Rank =
RANKX(
ALL(Products[Product Name]),
[Total Sales],
,
DESC,
Dense
)
Top N Pattern
/// Sales from top 10 products only
Top 10 Products Sales =
CALCULATE(
[Total Sales],
TOPN(
10,
ALL(Products[Product Name]),
[Total Sales],
DESC
)
)
Table Functions
SUMMARIZE
/// Sales summary by category
Category Summary =
SUMMARIZE(
Sales,
Products[Category],
"Total Sales", [Total Sales],
"Avg Price", AVERAGE(Sales[Unit Price])
)
ADDCOLUMNS
/// Products with calculated fields
Products Extended =
ADDCOLUMNS(
Products,
"Sales Amount", [Total Sales],
"Rank", [Product Rank]
)
FILTER
/// High-value orders only
High Value Orders =
CALCULATE(
[Order Count],
FILTER(
Sales,
Sales[Amount] > 1000
)
)
Variables (VAR/RETURN)
Always use variables for:
- Reused expressions (calculate once)
- Complex logic (readability)
- Intermediate calculations
/// Complex calculation with variables
Profit Analysis =
VAR TotalRevenue = SUM(Sales[Revenue])
VAR TotalCost = SUM(Sales[Cost])
VAR TotalProfit = TotalRevenue - TotalCost
VAR ProfitMargin = DIVIDE(TotalProfit, TotalRevenue, 0)
VAR MarginCategory =
SWITCH(
TRUE(),
ProfitMargin >= 0.3, "High",
ProfitMargin >= 0.1, "Medium",
"Low"
)
RETURN
MarginCategory
Error Handling
IFERROR
/// Safe calculation with fallback
Safe Ratio =
IFERROR(
[Total Sales] / [Total Cost],
0
)
COALESCE for Blank Handling
/// Replace blank with zero
Sales or Zero =
COALESCE([Total Sales], 0)
ISBLANK Check
/// Conditional formatting flag
Has Sales =
NOT(ISBLANK([Total Sales]))
TMDL Measure Format
Measures in TMDL files:
/// Year-to-date sales calculation
/// Use with Date table marked as date table
measure 'Sales YTD' =
CALCULATE(
[Total Sales],
DATESYTD(Date[Date])
)
formatString: "$#,##0.00"
displayFolder: Time Intelligence
lineageTag: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Boundaries and Constraints
DO
- Always use DIVIDE() instead of
/operator - Always use VAR for reused expressions
- Add descriptions using
///comments - Use meaningful variable names
- Format complex expressions across multiple lines
- Group related measures in displayFolders
- Test measures with different filter contexts
DO NOT
- Never use implicit measures (drag-and-drop aggregations)
- Never nest CALCULATE more than 2-3 levels deep
- Avoid IFERROR around aggregations (masks data issues)
- Never reference measure results in calculated columns
- Avoid circular references between measures
- Never hardcode filter values when parameters work
Workflow Integration
After creating measures:
- Test measures - Verify calculations in a visual
- Validate - Use the
best-practicesskill to check DAX quality - Add to reports - Use the
report-visualsskill to display
Common Issues
"Circular dependency"
Measures reference each other in a loop. Break the cycle by restructuring.
"Column not found"
Check table and column names match exactly (case-sensitive).
"Cannot convert value"
Data type mismatch. Ensure compatible types in comparisons.
"The value for column cannot be determined"
Filter context removed something needed. Review CALCULATE modifiers.
Related Skills
Attack Tree Construction
Build comprehensive attack trees to visualize threat paths. Use when mapping attack scenarios, identifying defense gaps, or communicating security risks to stakeholders.
Grafana Dashboards
Create and manage production Grafana dashboards for real-time visualization of system and application metrics. Use when building monitoring dashboards, visualizing metrics, or creating operational observability interfaces.
Matplotlib
Foundational plotting library. Create line plots, scatter, bar, histograms, heatmaps, 3D, subplots, export PNG/PDF/SVG, for scientific visualization and publication figures.
Scientific Visualization
Create publication figures with matplotlib/seaborn/plotly. Multi-panel layouts, error bars, significance markers, colorblind-safe, export PDF/EPS/TIFF, for journal-ready scientific plots.
Seaborn
Statistical visualization. Scatter, box, violin, heatmaps, pair plots, regression, correlation matrices, KDE, faceted plots, for exploratory analysis and publication figures.
Shap
Model interpretability and explainability using SHAP (SHapley Additive exPlanations). Use this skill when explaining machine learning model predictions, computing feature importance, generating SHAP plots (waterfall, beeswarm, bar, scatter, force, heatmap), debugging models, analyzing model bias or fairness, comparing models, or implementing explainable AI. Works with tree-based models (XGBoost, LightGBM, Random Forest), deep learning (TensorFlow, PyTorch), linear models, and any black-box model
Pydeseq2
Differential gene expression analysis (Python DESeq2). Identify DE genes from bulk RNA-seq counts, Wald tests, FDR correction, volcano/MA plots, for RNA-seq analysis.
Query Writing
For writing and executing SQL queries - from simple single-table queries to complex multi-table JOINs and aggregations
Pydeseq2
Differential gene expression analysis (Python DESeq2). Identify DE genes from bulk RNA-seq counts, Wald tests, FDR correction, volcano/MA plots, for RNA-seq analysis.
Scientific Visualization
Meta-skill for publication-ready figures. Use when creating journal submission figures requiring multi-panel layouts, significance annotations, error bars, colorblind-safe palettes, and specific journal formatting (Nature, Science, Cell). Orchestrates matplotlib/seaborn/plotly with publication styles. For quick exploration use seaborn or plotly directly.
