DAX语言学习教程

Mastering DAX: From Zero to Hero 数据分析表达式的视觉指南 什么是 DAX? DAX (Data Analysis Expressions) 是一种函数公式语言,用于在 Power BI、Analysis Services 和 Excel 中的 Power Pivot 等分析工具中创建自定义计算。它不是一种编程语言,而是一组可以在公式中使用以计算和返回一个或多个值的函数、运算符和常量集合。它的主要目的是操作数据模型,而不是像 Excel 那样操作单个单元格。 计算列 (Calculated Columns) 在数据刷新时计算一次,并物理存储在模型中。它们在 行上下文(Row Context) 中工作——公式只能看到当前行的值。 → 使用场景: 结果需要用于筛选器或图表轴。 计算是静态的,并且依赖于行。 你想在数据表中看到结果。 度量值 (Measures) 在可视化使用时动态计算。它们不会存储在模型中。它们在 筛选器上下文(Filter Context) 中工作——公式会响应来自图表、切片器等的筛选条件。 Σ 使用场景: 你需要动态聚合(例如:销售额总和)。 结果需要是图表上的值。 计算必须响应用户交互。 概念 1:计算上下文 理解上下文是掌握 DAX 的关键。每个计算都在特定的上下文中进行,该上下文定义了公式“可见”哪些数据。 行上下文 (Row Context) “我查看的是这一行”。它出现在计算列和迭代函数(例如 SUMX)中。公式只能访问当前行的列值。 筛选上下文 (Filter Context) “我查看的是经过筛选的数据集”。指可视化中活动的筛选器集合(来自轴、图例、切片器)。度量值在这种上下文中工作。 基本函数:迭代器 vs 聚合 聚合函数(例如 `SUM`)在活动筛选上下文的整个列上工作。迭代函数(末尾带 "X",例如 `SUMX`)逐行遍历(创建行上下文),执行计算,最后聚合结果。这对于基于多个列的计算至关重要,例如 `数量 * 单价`。 示例:总销售额 Total Sales (SUMX) = SUMX( 'Sales', 'Sales'[Quantity] * 'Sales'[Net Price] ) 上述 `SUMX` 公式会遍历 'Sales' 表中的每一行,将该行的数量乘以价格,然后对所有结果求和,从而得出准确的总销售额。 `CALCULATE()` 函数:上下文修改引擎 `CALCULATE` 是 DAX 中最重要的函数。它允许修改度量值计算的筛选器上下文。这是一个用于提出分析性问题的工具,例如:“产品 X 的销售额是多少?”或“忽略所有筛选器的销售额是多少?” 表达式 [Total Sales] + 筛选器修改器 1 'Product'[Category] = "Laptops" + 筛选器修改器 2 ALL('Date') = 新结果 所有日期笔记本电脑销售额 Sales Laptops = CALCULATE( [Total Sales], 'Product'[Category] = "Laptops" ) 上下文修改:`ALL()` 像 `ALL()`、`ALLEXCEPT()` 或 `REMOVEFILTERS()` 这样的函数用于从上下文中移除筛选器。`ALL()` 会移除给定表或列中的所有筛选器。这对于计算占总体的百分比份额至关重要,例如“某一类别的销售额占总销售额的比例”。 示例:销售额占比 % of Total Sales = DIVIDE( [Total Sales], CALCULATE( [Total Sales], ALL('Product') ) ) 在包含 `ALL('Product')` 的 `CALCULATE` 中,它计算总销售额,忽略应用于产品表的任何筛选器。这样我们就可以将某一类别的销售额(分子)与所有类别销售额的总和(分母)进行比较。 时间智能:时间分析 DAX 拥有强大的时间智能功能集,用于进行时间数据分析。它们要求模型中必须包含正确的日历表。它们可以轻松计算指标,例如去年同期销售额(Year-over-Year)或累计总和(Running Total)。 示例:同比增长销售额 (YoY) Sales Last Year = CALCULATE( [Total Sales], SAMEPERIODLASTYEAR('Date'[Date]) ) `SAMEPERIODLASTYEAR` 函数将日期上下文向后移动一年。将其用于 `CALCULATE` 内部,可以计算出完全相同时间段但在前一年的 `[Total Sales]` 指标,从而实现增长比较。 指标 1:利润率 % 计算利润占收入的百分比。 Margin % = DIVIDE( [Total Profit], [Total Sales] ) 指标 2:同比增长率 % 计算销售额相对于前一年的百分比增长。 Sales YoY Growth % = DIVIDE( [Total Sales] - [Sales Last Year], [Sales Last Year] ) +15.2% 同比销售增长 指标 3:累计总和 (YTD) 计算从年初到当前日期的累计销售额。 Sales YTD = TOTALYTD( [Total Sales], 'Date'[Date] ) €1.25M 年初至今的销售额 扩展 DAX 公式词典 聚合和迭代函数 SUM / AVERAGE / MIN / MAX 基本聚合:求和、计算平均值、查找列中的最小值或最大值。 Total Sales = SUM('Sales'[Amount]) COUNTROWS 计算表中行数。 Number of Transactions = COUNTROWS('Sales') DISTINCTCOUNT 计算列中的唯一值。 Unique Customers = DISTINCTCOUNT('Sales'[CustomerID]) SUMX / AVERAGEX / MINX / MAXX 迭代版本:为每一行计算表达式,然后聚合结果。 Total Revenue = SUMX('Sales', 'Sales'[Quantity] * 'Sales'[Price]) 筛选和上下文函数 FILTER 根据条件返回另一个表的子集。 High Value Sales = CALCULATE([Total Sales], FILTER('Sales', 'Sales'[Amount] > 1000)) ALL / ALLEXCEPT / ALLSELECTED 通过移除筛选器(ALL)、排除例外(ALLEXCEPT)或仅考虑可视化中的筛选器(ALLSELECTED)来修改筛选上下文。 % of Category = DIVIDE([Total Sales], CALCULATE([Total Sales], ALLEXCEPT('Product', 'Product'[Category]))) KEEPFILTERS 应用新筛选器,同时保留现有上下文,而不是覆盖它。 Blue Laptops Sales = CALCULATE([Total Sales], KEEPFILTERS('Product'[Color] = "Blue")) VALUES / DISTINCT 返回一个包含唯一值的单列表。 Products With Sales = COUNTROWS(VALUES('Sales'[ProductID])) 时间函数(Time Intelligence) DATEADD / PARALLELPERIOD / SAMEPERIODLASTYEAR 用于时间周期移位进行比较的函数。 Sales Previous Month = CALCULATE([Total Sales], DATEADD('Date'[Date], -1, MONTH)) DATESYTD / DATESQTD / DATESMTD 返回从年初/季度初/月初到上下文中的最后日期的日期表。 Sales Year-To-Date = CALCULATE([Total Sales], DATESYTD('Date'[Date])) STARTOF...

/ ENDOF...

(MONTH, QUARTER, YEAR) 返回期间的起始日期或结束日期。 Sales on Last Day of Month = CALCULATE([Total Sales], ENDOFMONTH('Date'[Date])) 逻辑和条件函数 IF / SWITCH 用于实现条件逻辑。IF 用于简单条件,SWITCH 用于多个可能结果。 Price Segment = SWITCH(TRUE(), 'Product'[Price] AND (&&) / OR (||) / NOT 用于组合多个条件的逻辑运算符。 High Value Electronics = CALCULATE([Total Sales], 'Product'[Category] = "Electronics" && 'Sales'[Amount] > 1000) ISBLANK / ISERROR 检查表达式是否为空或返回错误。在 DIVIDE 中很有用。 Safe Division = IF(NOT(ISBLANK([Denominator])), DIVIDE([Numerator], [Denominator]), 0) 文本函数 CONCATENATE (&) / COMBINEVALUES 连接文本字符串。 Customer Full Name = 'Customer'[FirstName] & " " & 'Customer'[LastName] FORMAT 将值转换为指定格式的文本。 Formatted Sales = "Sales: " & FORMAT([Total Sales], "Currency") LEFT / RIGHT / MID 提取文本字符串的一部分。 Product Code Prefix = LEFT('Product'[ProductCode], 2) 高级表格函数 SUMMARIZE / ADDCOLUMNS 创建虚拟表。SUMMARIZE 用于分组数据,ADDCOLUMNS 向表中添加新的计算列。 Sales By Category = SUMMARIZE('Product', 'Product'[Category], "Total Sales", [Total Sales]) RANKX 返回指定表达式当前上下文的排名位置。 Product Rank by Sales = RANKX(ALL('Product'), [Total Sales]) GENERATE / CROSSJOIN 它们创建了两个表之间的笛卡尔积(所有可能的行组合)。 All Product-Customer Pairs = CROSSJOIN(VALUES('Product'[Product]), VALUES('Customer'[Customer]))