Power BI 速查表
最后更新
度量值、列和表
度量值在视觉对象的每个单元格中计算;计算列按行计算一次并存储。
| 作用 | DAX |
|---|---|
| 创建度量值 | Total Sales = SUM ( Sales[Amount] ) |
| 创建计算列(每行一个值) | Line Total = Sales[Quantity] * Sales[Unit Price] |
| 创建计算表 | Top Customers = TOPN ( 10, Customer, [Total Sales] ) |
| 引用列:先写表名,再把列名放在方括号里 | Sales[Amount] |
| 表名含空格或是保留字时,用引号括起来 | 'Date'[Date] |
| 引用度量值:只用方括号 | [Total Sales] |
| 在一个度量值中使用另一个度量值 | Average Price = DIVIDE ( [Total Sales], [Total Units] ) |
聚合函数
每个函数都在当前筛选上下文中汇总一列。
| 作用 | DAX |
|---|---|
| 对一列求和 | SUM ( Sales[Amount] ) |
| 一列的平均值 | AVERAGE ( Sales[Amount] ) |
| 最小值 | MIN ( Sales[Order Date] ) |
| 最大值 | MAX ( Sales[Order Date] ) |
| 统计表的行数 | COUNTROWS ( Sales ) |
| 统计一列中非空值的个数 | COUNT ( Sales[Amount] ) |
| 统计不重复值的个数 | DISTINCTCOUNT ( Sales[Customer Key] ) |
| 安全除法:分母为 0 时返回空值而不是错误 | DIVIDE ( [Total Sales], [Total Units] ) |
| 除法,并指定分母为 0 时显示的值 | DIVIDE ( [Profit], [Total Sales], 0 ) |
迭代器(X 函数)
它们逐行遍历一张表,对每一行计算表达式,再汇总结果。
| 作用 | DAX |
|---|---|
| 逐行相乘,再求和 | SUMX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| 逐行结果的平均值 | AVERAGEX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| 逐行结果中的最大值 | MAXX ( Sales, Sales[Quantity] * Sales[Unit Price] ) |
| 每位客户的度量值平均值 | AVERAGEX ( VALUES ( Customer[Customer Key] ), [Total Sales] ) |
| 在表达式中使用相关表的列 | SUMX ( Sales, Sales[Quantity] * RELATED ( Product[Unit Cost] ) ) |
| 统计满足条件的行数 | COUNTROWS ( FILTER ( Sales, Sales[Quantity] >= 3 ) ) |
| 按度量值给所有产品排名 | RANKX ( ALL ( Product[Product] ), [Total Sales] ) |
| 并列之后不跳号的排名(1, 1, 2) | RANKX ( ALL ( Product[Product] ), [Total Sales], , DESC, DENSE ) |
| 把多个值连接成一段文本 | CONCATENATEX ( VALUES ( Product[Category] ), Product[Category], ", " ) |
CALCULATE 和筛选函数
CALCULATE 在更改后的筛选器下计算表达式。同一列上的新筛选器会替换原来的筛选器;不同列上的筛选器以 AND 组合。
| 作用 | DAX |
|---|---|
| 按一个值筛选 | CALCULATE ( [Total Sales], Product[Category] = "Bikes" ) |
| 按一组值筛选 | CALCULATE ( [Total Sales], Product[Color] IN { "Red", "Blue" } ) |
| 两个筛选器(AND) | CALCULATE ( [Total Sales], Product[Color] = "Red", Store[Country] = "Spain" ) |
| 跨两列的 OR | CALCULATE ( [Total Sales], FILTER ( ALL ( Product[Color], Product[Brand] ), Product[Color] = "Red" || Product[Brand] = "Contoso" ) ) |
| 按度量值筛选 | CALCULATE ( [Total Sales], FILTER ( VALUES ( Customer[Customer Key] ), [Total Sales] > 1000 ) ) |
| 保留现有筛选器,并与之取交集 | CALCULATE ( [Total Sales], KEEPFILTERS ( Product[Color] IN { "Red", "Blue" } ) ) |
| 移除某一列上的筛选器 | CALCULATE ( [Total Sales], REMOVEFILTERS ( Product[Category] ) ) |
| 移除一张表上的所有筛选器 | CALCULATE ( [Total Sales], ALL ( Product ) ) |
| 移除表上除某些列以外的所有筛选器 | CALCULATE ( [Total Sales], ALLEXCEPT ( Store, Store[Country] ) ) |
| 保留切片器的选择,去掉视觉对象自身行的筛选 | CALCULATE ( [Total Sales], ALLSELECTED ( Product[Category] ) ) |
| 使用非活动关系 | CALCULATE ( [Total Sales], USERELATIONSHIP ( Sales[Ship Date], 'Date'[Date] ) ) |
| 只在一个度量值中让筛选双向传递 | CALCULATE ( COUNTROWS ( Customer ), CROSSFILTER ( Sales[Customer Key], Customer[Customer Key], BOTH ) ) |
| 按一张没有关系的表筛选 | CALCULATE ( [Total Sales], TREATAS ( VALUES ( Budget[Category] ), Product[Category] ) ) |
时间智能
这些函数需要日期表:每天一行,没有缺口,并标记为日期表。
| 作用 | DAX |
|---|---|
| 年初至今 | TOTALYTD ( [Total Sales], 'Date'[Date] ) |
| 年初至今(财年截至 6 月 30 日) | TOTALYTD ( [Total Sales], 'Date'[Date], "6/30" ) |
| 在 CALCULATE 中计算年初至今 | CALCULATE ( [Total Sales], DATESYTD ( 'Date'[Date] ) ) |
| 季初至今 | TOTALQTD ( [Total Sales], 'Date'[Date] ) |
| 月初至今 | TOTALMTD ( [Total Sales], 'Date'[Date] ) |
| 去年同期 | CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) |
| 按间隔平移日期(这里是往前一个月) | CALCULATE ( [Total Sales], DATEADD ( 'Date'[Date], -1, MONTH ) ) |
| 上个月整月 | CALCULATE ( [Total Sales], PREVIOUSMONTH ( 'Date'[Date] ) ) |
| 往前一年的整个期间 | CALCULATE ( [Total Sales], PARALLELPERIOD ( 'Date'[Date], -1, YEAR ) ) |
| 截至最后一个可见日期的最近 12 个月 | CALCULATE ( [Total Sales], DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -12, MONTH ) ) |
| 固定日期范围 | CALCULATE ( [Total Sales], DATESBETWEEN ( 'Date'[Date], DATE ( 2025, 1, 1 ), DATE ( 2025, 3, 31 ) ) ) |
常用度量值模式
复制后,把表名和列名改成你模型中的名字。
| 作用 | DAX |
|---|---|
| 占所有类别的百分比 | Category % = DIVIDE ( [Total Sales], CALCULATE ( [Total Sales], REMOVEFILTERS ( Product[Category] ) ) ) |
| 占切片器筛选后范围的百分比 | Visible % = DIVIDE ( [Total Sales], CALCULATE ( [Total Sales], ALLSELECTED ( Product[Category] ) ) ) |
| 同比增长 | YoY % = VAR LastYear = CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) RETURN DIVIDE ( [Total Sales] - LastYear, LastYear ) |
| 所有时间的累计总计 | Running Total = CALCULATE ( [Total Sales], FILTER ( ALL ( 'Date'[Date] ), 'Date'[Date] <= MAX ( 'Date'[Date] ) ) ) |
| 7 日移动平均(按有销售的天计算) | Sales 7 Day Avg = AVERAGEX ( DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -7, DAY ), [Total Sales] ) |
| 只为前 5 名显示值 | Top 5 Sales = IF ( RANKX ( ALLSELECTED ( Product[Product] ), [Total Sales] ) <= 5, [Total Sales] ) |
| 统计超过阈值的客户数 | Big Customers = COUNTROWS ( FILTER ( VALUES ( Customer[Customer Key] ), [Total Sales] > 1000 ) ) |
| 让总计等于各行之和 | Bonus Total = SUMX ( VALUES ( Product[Category] ), [Bonus] ) |
| 只在矩阵的某一层级显示值 | Category Rank = IF ( ISINSCOPE ( Product[Category] ), RANKX ( ALL ( Product[Category] ), [Total Sales] ) ) |
| 期末余额:最后一个有值的日期 | Closing Units = CALCULATE ( SUM ( Inventory[Units] ), LASTNONBLANK ( 'Date'[Date], CALCULATE ( SUM ( Inventory[Units] ) ) ) ) |
逻辑函数和信息函数
用于判断条件,以及查看筛选上下文中保留了什么。
| 作用 | DAX |
|---|---|
| 一个条件 | IF ( [Total Sales] > 1000, "High", "Low" ) |
| 一个表达式的多个取值 | SWITCH ( Store[Country], "Spain", "ES", "Portugal", "PT", "Other" ) |
| 按范围从上到下判断 | SWITCH ( TRUE (), [Total Sales] >= 10000, "A", [Total Sales] >= 1000, "B", "C" ) |
| AND 和 OR | IF ( Sales[Quantity] > 2 && Sales[Amount] > 50, "Big", "Small" ) |
| 值是否为空? | ISBLANK ( [Total Sales] ) |
| 第一个非空值 | COALESCE ( [Total Sales], 0 ) |
| 筛选后是否恰好只剩一个值? | HASONEVALUE ( Product[Category] ) |
| 那个唯一的值,否则返回默认值 | SELECTEDVALUE ( Product[Category], "All categories" ) |
| 视觉对象的这一行是否按该列分组? | ISINSCOPE ( Product[Category] ) |
| 返回空值 | BLANK () |
文本函数
& 运算符连接文本;FORMAT 把数字或日期变成文本。
| 作用 | DAX |
|---|---|
| 连接文本 | Customer[First Name] & " " & Customer[Last Name] |
| 设置数字格式 | FORMAT ( [Total Sales], "#,0.00" ) |
| 设置日期格式 | FORMAT ( 'Date'[Date], "mmm yyyy" ) |
| 开头的几个字符 | LEFT ( Product[Code], 3 ) |
| 从某个位置开始的字符 | MID ( Product[Code], 4, 2 ) |
| 长度 | LEN ( Product[Name] ) |
| 转为大写 | UPPER ( Store[City] ) |
| 删除多余空格 | TRIM ( Customer[Name] ) |
| 替换文本 | SUBSTITUTE ( Customer[Phone], " ", "" ) |
| 查找文本的位置,不区分大小写(找不到时为 0) | SEARCH ( "pro", Product[Name], 1, 0 ) |
日期函数
日期本质上是数字,所以两个日期相减就得到天数。
| 作用 | DAX |
|---|---|
| 今天的日期 | TODAY () |
| 构造日期 | DATE ( 2025, 12, 31 ) |
| 日期的年份 | YEAR ( 'Date'[Date] ) |
| 月份数字 | MONTH ( 'Date'[Date] ) |
| 星期几(周一为 1) | WEEKDAY ( 'Date'[Date], 2 ) |
| 周数(每周从周一开始) | WEEKNUM ( 'Date'[Date], 2 ) |
| 月末日期 | EOMONTH ( 'Date'[Date], 0 ) |
| 一个月前的同一天 | EDATE ( 'Date'[Date], -1 ) |
| 两个日期之间的天数 | DATEDIFF ( Sales[Order Date], Sales[Ship Date], DAY ) |
| 用固定日期生成日期表 | CALENDAR ( DATE ( 2024, 1, 1 ), DATE ( 2025, 12, 31 ) ) |
| 用模型中的日期生成日期表 | CALENDARAUTO () |
关系和查找
RELATED 沿着关系从多端走到一端。
| 作用 | DAX |
|---|---|
| 一端的值(在 Sales 表的列中) | RELATED ( Product[Category] ) |
| 当前行在多端对应的行(在 Customer 表的列中) | COUNTROWS ( RELATEDTABLE ( Sales ) ) |
| 在没有关系时查找值 | LOOKUPVALUE ( Product[Price], Product[SKU], Sales[SKU] ) |
| 父子路径(用于层次结构和行级别安全性) | PATH ( Employee[Employee ID], Employee[Manager ID] ) |
| 当前登录的用户,用于动态行级别安全性 | USERPRINCIPALNAME () |
表函数
它们返回表:可以用在计算表中、CALCULATE 里或迭代器中。
| 作用 | DAX |
|---|---|
| 当前筛选下的不重复值 | VALUES ( Product[Category] ) |
| 满足条件的行 | FILTER ( Product, Product[Price] > 100 ) |
| 按度量值取前 N 行 | TOPN ( 5, ALL ( Product[Product] ), [Total Sales] ) |
| 按列分组并添加度量值 | SUMMARIZECOLUMNS ( Product[Category], "Sales", [Total Sales] ) |
| 给表添加一列 | ADDCOLUMNS ( VALUES ( Product[Category] ), "Sales", [Total Sales] ) |
| 选择列并重命名 | SELECTCOLUMNS ( Customer, "Name", Customer[Name], "City", Customer[City] ) |
| 一串数字 | GENERATESERIES ( 1, 10, 1 ) |
| 两张表的所有组合 | CROSSJOIN ( VALUES ( 'Date'[Year] ), VALUES ( Product[Category] ) ) |
| 把列相同的两张表上下堆叠 | UNION ( 'Sales 2024', 'Sales 2025' ) |
变量
VAR 给一个步骤命名并只计算一次;RETURN 给出结果。
| 作用 | DAX |
|---|---|
| 一个变量 | Margin % = VAR Revenue = [Total Sales] RETURN DIVIDE ( Revenue - [Total Cost], Revenue ) |
| 多个变量 | Sales vs LY = VAR CY = [Total Sales] VAR PY = CALCULATE ( [Total Sales], SAMEPERIODLASTYEAR ( 'Date'[Date] ) ) RETURN CY - PY |
| 把表存进变量 | Top 5 Total = VAR Top5 = TOPN ( 5, ALL ( Product[Product] ), [Total Sales] ) RETURN CALCULATE ( [Total Sales], Top5 ) |
Power Query(M)步骤
Power Query 在加载前整理数据。这些是常用按钮背后的 M 公式。
| 作用 | M |
|---|---|
| 保留符合条件的行 | Table.SelectRows(Source, each [Status] = "Paid") |
| 删除列 | Table.RemoveColumns(Source, {"Notes", "Temp"}) |
| 设置列类型 | Table.TransformColumnTypes(Source, {{"Amount", type number}, {"Date", type date}}) |
| 重命名列 | Table.RenameColumns(Source, {{"amt", "Amount"}}) |
| 添加列 | Table.AddColumn(Source, "Total", each [Quantity] * [Price], type number) |
| 合并(联接)两个查询 | Table.NestedJoin(Sales, {"ProductID"}, Products, {"ProductID"}, "Product", JoinKind.LeftOuter) |
| 追加(堆叠)查询 | Table.Combine({Sales2024, Sales2025}) |
| 将列逆透视为行 | Table.UnpivotOtherColumns(Source, {"Product"}, "Month", "Amount") |
| 分组并聚合 | Table.Group(Source, {"Category"}, {{"Sales", each List.Sum([Amount]), type number}}) |
| 用一个值替换错误 | Table.ReplaceErrorValues(Source, {{"Amount", 0}}) |
这份 Power BI 速查表把最常写的 DAX 放在一页上:聚合函数、X 迭代器、CALCULATE 和更改筛选器的函数、时间智能、文本和日期函数,以及可以直接复制的度量值模式,比如占总计的百分比、同比增长和累计总计。
示例使用一个销售模型,其中有 Sales、Product、Customer 和 'Date' 表;请把表名改成你自己模型中的名字。这里所有的 DAX 都经过 Coddy Power BI 课程所用引擎的语法检查。在课程中,你可以在浏览器的 Power BI 工作区里写 DAX,并得到检查结果。
Power BI 速查表常见问题
这份 Power BI 速查表免费吗?
免费。可以直接在这里看,也可以收藏起来,无需注册。
度量值和计算列有什么区别?
计算列在刷新时按行计算一次并存储,所以可以用它来切片。度量值在视觉对象的每个单元格中按该单元格的筛选器计算,不存储任何数据。总计和比率应该写成度量值。
CALCULATE 有什么作用?
它在更改后的筛选器下计算表达式:先添加、替换或移除筛选器,再计算结果。除了简单的总计,大多数 DAX 都是带有合适筛选参数的 CALCULATE。
为什么用 DIVIDE 而不用 / 运算符?
DIVIDE 返回空值(或你指定的值)。/ 运算符则会返回无穷大或错误值,并显示在视觉对象中。时间智能需要日期表吗?
TOTALYTD 和 SAMEPERIODLASTYEAR 等函数需要一张每天一行、没有缺口、覆盖完整年份的表,它要与事实表建立关系,并标记为日期表。这些 DAX 在 Excel Power Pivot 和 Analysis Services 中能用吗?
DAX 语言是通用的,所以几乎都能用。少数较新的函数会先在 Power BI 中推出。
在哪里可以练习 DAX?
在 Coddy 的 Power BI 课程中。每节课都会在浏览器中给你一个 Power BI 工作区,并用本课的数据和它的隐藏副本检查你的度量值。