PowerBI开发 第四篇:DAX表达式
DAX 表达式主要用于创建度量列(Measure),度量值是根据用户选择的Filter和公式,计算聚合值,DAX表达式基本上都是引用对应的函数,函数的执行有表级(Table-Level)上下文和行级(Row-Level)上下文之别;其交互行为都是通过表之间的关系实现的,用户选择的Filter,会通过关系对数据进行过滤,是PowerBI报表呈现的数据具有动态交互的特性。在我开发的PowerBI报表项目中,经常使用的DAX表达式函数,其实并不是很多,本文分享一些入门级的常用函数,附上简单的注释,希望对新手设计PowerBI报表有所帮助。
一,常用的操作符
在DAX表达式中,常用的操作符是:
- 文本使用双引号作为界定符,
- 等号是“=”号,不等号是:<>
- 赋值使用“=”号,
- 布尔值使用 TRUE()和FALSE()函数,
- 空值使用BLANK()函数表示,
- 集合使用大括号{}表示,例如,包含三个item的集合: {1,2,3}
- 字符的连接符号是:&
- 逻辑运算符号是:逻辑与是 &&,逻辑或是: ||
二,过滤函数
过滤函数能够操作数据的上下文,以实现数据的动态计算,功能非常强大。
1,关联函数
Related函数返回跟当前的数据行有关系的表的单个值,
RELATED(related_table[column])
Related函数要求当前表和关联表之间存在关系(Relationship),当前表和关联表之间存在many-to-one的关系,从关联表中返回单个值。
Related函数运行在行上下文(row context),因此,只能用于计算列的表达式。
示例:表InternetSales_USD和SalesTerritory之间存在关系,从表SalesTerritory获取SalesTerritoryCountry的值,并通过FILTER函数进行过滤,统计表InternetSales_USD中字段[SalesAmount_USD]的加和:
= SUMX(FILTER( 'InternetSales_USD', RELATED('SalesTerritory'[SalesTerritoryCountry]) <>"United States" ) ,'InternetSales_USD'[SalesAmount_USD])
RELATEDTABLE 用于one-to-many的关系,用于返回被过滤的所有数据行组成的表。
2,过滤函数
Filter函数,返回被过滤之后的表,是表数据的子集:
FILTER(<table>,<filter>)
通过过滤条件,获取表的子集,过滤函数返回的表只能用于计算。过滤函数不是独立的,必须嵌入(embedded)到其他函数中作为一个表值参数。
3,计算函数
Calculate函数,在过滤器的上下文中计算表达式,返回单个值:
CALCULATE(<expression>,<filter1>,<filter2>…)
参数expression是计算的表达式,受到filter参数的上下文的影响,如果filter参数改变数据的上下文,那么在新的上下文中计算表达式。计算函数的最大特点是能够移除过滤器,在过滤参数中,如果数据列上已经存在一个过滤器,那么移除该过滤器,应用当前的过滤器。
For each column used in a filter argument, any existing filters on that column are removed, and the filter used in the filter argument is applied instead.
示例:在计算比例关系时,使用计算函数的移除过滤器的功能:
=( SUM('ResellerSales_USD'[SalesAmount_USD])) /CALCULATE( SUM('ResellerSales_USD'[SalesAmount_USD]) ,ALL('ResellerSales_USD'))
表达式中的分母,使用计算函数,其中,第一个过滤器参数使用ALL过滤函数,使得sum表达式统计所有的数据行,这种行为重写对数据表的隐式过滤器。
4,移除过滤器
ALL函数返回表中的所有数据行,清理任意过滤器,用于对全表执行聚合运算。ALL函数主要用于计算比例关系,常用于分母中。
ALL( {<table> | <column>)
5,去重函数
Distinct 返回单列的表,包含无重复的值,也就是说,从表中移除重复值,只返回列的唯一值。
DISTINCT(<column>)
6,过滤器的值
函数Values返回被过滤的唯一值,在同一个表中的其他Column被过滤,那么返回被过滤的当前Column的唯一值。Values函数和Distinct函数很相似,唯一的不同是Values函数会返回Unknown,这是因为关联的Table中包含部匹配的数据行,和Left Join的右表中包含NULL值很相似。
VALUES(<TableNameOrColumnName>)
When you use the VALUES function in a context that has been filtered, the unique values returned by VALUES are affected by the filter.
结合CONCATENATEX函数,能够把所有过滤器的值连接成字符串。注意,DAX表达式使用 & 进行字符串的连接。
7,探测直接过滤(filtered directly)
如果指定的Column被直接过滤(filtered directly),函数返回True;当同一个Table中的其他Column被过滤,切片器(Slicer)中被关联的Column,默认设置是全部直接过滤,函数返回True;如果Column上没有直接的过滤,或者同一个Table中的其他Column被过滤,或者被有关系的Table过滤,函数返回False。
ISFILTERED(<columnName>)
直接过滤器的数值通过函数Filters返回:
FILTERS(<columnName>)
8,探测关联过滤
如果同一个Table中的其他Column被过滤,或者被有关系的Table过滤,函数返回True
ISCROSSFILTERED(<columnName>)
9,保持过滤器
函数 KeepFilters 的作用是保持过滤器,用于计算函数(CALCULATE 和 CALCULATETABLE)中。默认情况下,计算函数的过滤器参数(filter argument)会对过滤表数据,当在相同的字段上设置过滤器参数(filter argument)时,该参数会替换已经存在的过滤器;当相同的字段上没有过滤器参数(filter argument)时,已经存在的过滤器不受影响。函数KeepFilters会改变计算函数的行为,当在计算函数使用函数KeepFilters时,表的上下文是过滤器参数(filter argument)和已经存在的过滤器的交集,也就是说,表的上下文同时受到已经存在的过滤器和计算函数的过滤器参数(filter argument)的影响。计算函数替换已经存在的过滤器,而函数 KeepFilters会添加已经存在的过滤,求交集。
KEEPFILTERS(<expression>)
三,统计函数
统计函数是最强力的函数,同时也是最复杂的函数,为数据的分析,提供非常强力的工具,同时,在使用统计函数时,必须考虑到数据模型,表之间关系,数据重复等因素,一般都会搭配过滤函数实现数据的提取和分析。
1,求和函数
从表中计算每一个行的加和,只有数值会被加和,忽略空值,date,逻辑值或文本值:
SUMX(<table>, <expression>)
示例,第一个参数是过滤器返回的表值,计算[Freight]的加和:
=SUMX(FILTER(InternetSales, InternetSales[SalesTerritoryID]=5),[Freight])
可以把SUMX函数,转换为CALCULATE函数:
=CALCULATE( SUM(InternetSales[Freight]), FILTER(InternetSales, InternetSales[SalesTerritoryID]=5))
2,计数函数
计算函数分为:COUNTX和COUNTAX,COUNTX只统计数值,忽略空值(blank),date,逻辑值或文本值;COUNTAX函数统计非空值(blank),包含数值,date,逻辑值或文本值。
COUNTX(<table>,<expression>) COUNTAX(<table>,<expression>)
例外:如果列中包含表达式,而表达式的结果是空值,但是,COUNTAX/COUNTX函数把包含公式的列值作为非空(nonblank)看待,在这种情况下,计数函数会增加计数值。
如果COUNTAX函数没有数据列做计数,返回blank;如果COUNTAX函数聚合的数据列都是blank,返回0。
3,唯一值计数
统计列的唯一值计数,参数是表列,允许是任意数据类型,当找不到任何数据行时,返回BLANK,否则,统计唯一值的数量。
DISTINCTCOUNT(<column>)
4,分组聚合函数
DAX 中功能最强大的函数,对相互关联的Table按照特定的字段,分组聚合,由于分组列是唯一的,通过SUMMARIZE函数,可以获得多列的唯一值。
SUMMARIZE(<table>, <groupBy_columnName>[, <groupBy_columnName>]…[, <name>, <expression>]…)
示例:对数据表 ResellerSales_USD ,按照字段 DateTime[CalendarYear] 和 ProductCategory[ProductCategoryName]分组,计算 SUM(ResellerSales_USD[SalesAmount_USD])和 SUM(ResellerSales_USD[DiscountAmount]) 。
SUMMARIZE(ResellerSales_USD , DateTime[CalendarYear] , ProductCategory[ProductCategoryName] , "Sales Amount (USD)", SUM(ResellerSales_USD[SalesAmount_USD]) , "Discount Amount (USD)", SUM(ResellerSales_USD[DiscountAmount]) )
分组聚合函数,能够利用关系,引用相关表的字段,也就是说,SUMMARIZE函数能够对有关系的表执行连接(join)运算,计算笛卡尔乘积,对Join的结果集执行分组聚合,例如:
summarize('Internet Sales','Product'[Product Name],'Date'[Calendar Year],"Total Sales Amount", sum('Internet Sales'[Sales Amount]))
从数据表Date中获取字段Calendar Year的前提是,数据表Date和Internet Sales之间存在关系,从数据表Product中获取字段Product Name的前提是:数据表Product和Internet Sales之间存在关系。
分组聚合函数用于创建新表,在Modeling菜单中,通过“New Table”从DAX表达式中创建新的Table:
参考文档:SUMMARIZE – groupping in data models (DAX – Power Pivot, Power BI)
四,文本函数
在DAX表达式中,字符串使用双引号界定。
1,格式函数
按照指定的格式把值转换成文本
FORMAT(<value>, <format_string>)
2,空值
在DAX中,空值(Blank) 和数据库的NULL值是相同的,通过函数ISBLANK(value)判断当前的字段值是否是空值。
BLANK() ISBLANK(<value>)
3,查找函数
在一段文本中查找字符串时,从左向右读取文本,查找函数返回第一次匹配的字符的序号,序号从1开始,依次递增。search函数不区分大小写,而find函数区分大小写。
FIND(<find_text>, <within_text>[, [<start_num>][, <NotFoundValue>]]) SEARCH(<find_text>, <within_text>[, [<start_num>][, <NotFoundValue>]])
参数 NotFoundValue 是可选的,当查找不到匹配的子串时,返回该参数的值,一般设置为0,-1或BLANK()。
如果不设置该参数,而查找函数查找不到匹配的子串时,函数返回错误。可以通过IFERROR函数处理错误,例如:
= IFERROR(SEARCH("-",[PostalCode]),-1)
5,拼接函数
把表中的数据按照指定的分隔符拼接成字符串
CONCATENATEX(<table>, <expression>, [delimiter])
示例,Employees表中包含[FirstName] 和 [LastName]两列,把这两列拼接成一个字符串:
CONCATENATEX(Employees, [FirstName] & “ “ & [LastName], “,”)
五,逻辑函数
1,逻辑判断函数
检查逻辑条件是否满足,如果满足,返回value_if_true,如果不满足,返回value_if_false。
IF(logical_test>,<value_if_true>, <value_if_false>)
等于使用“=”表示,逻辑与使用“&&”表示,逻辑或使用“||”表示,而逻辑非,通常使用NOT()函数来实现:
NOT(<logical>)
2,布尔值函数
TRUE() FALSE()
通常用于表示数据库的bit类型的值
3,错误函数
如果表达式返回错误,返回value_if_error;如果表达式不返回错误,返回表达式的值。
IFERROR(expression, value_if_error)
错误函数等价于:
IFERROR(A,B) := IF(ISERROR(A), B, A)
4,包含逻辑
表(Table)表达式是由大括号构成的集合:{value1,value2,,vlaueN}
IN操作符的用法是:
<scalarExpr> IN <tableExpr>
包含行函数的用法是:
CONTAINSROW(<tableExpr>, <scalarExpr>[, <scalarExpr>, …])
示例,以下两个表达式是等价的:
[Color] IN { "Red", "Yellow", "Blue" } CONTAINSROW({ "Red", "Yellow", "Blue" }, [Color])
六,关系
1,为指定的关系指定查询时(query-time)的方向(cross-filtering direction)
函数CrossFilter使用已经存在的关系,重写的关系设置只在查询时有效。
CROSSFILTER(<columnName1>, <columnName2>, <direction>)
2,使用关系
函数UseRelationship只能使用已经存在的关系,通过关系两个端点(endpoint)来指定关系,关系的状态是不重要的,通常,使用该函数的目的是在Calculate函数中使用不活跃(Inactive)的关系。
USERELATIONSHIP(<columnName1>,<columnName2>)
参考文档:
DAX basics in Power BI Desktop
Data Analysis Expressions (DAX) Reference
PowerBI开发 第四篇:DAX表达式相关推荐
- 基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)
原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3945294.html. 上章节讲解了利用自主开发的组件SIP组件l ...
- Agv、Rgv 车辆控制调度系统开发第四篇
Agv.Rgv 车辆控制调度系统开发第四篇 车辆调度模拟器 前言 一.车辆模拟器是什么? 二.如何做模拟器 1.动作仿真模拟器 2.完全仿真模拟器 总结 下期预告 系列文章链接 其他文章 新篇章 前言 ...
- PowerBI开发 第十三篇:增量刷新
PowerBI 将要解锁增量刷新(Incremental refresh)功能,这是一个令人期待的更新,使得PowerBI可以加载大数据集,并能减少数据的刷新时间和资源消耗,该功能目前处于预览状态,只 ...
- PowerBI开发 第十篇:R 脚本
R是一种专门用于数据分析和统计的脚本语言,广泛应用在每一个需要统计和数据分析的领域.PowerBI支持R脚本,两者强强结合,使PowerBI的功能更加强大.PowerBI Desktop默认没有安装R ...
- Android Studio开发第四篇版本管理Git(下)
前面一片介绍了在as下如何关联远程仓库,这篇就介绍在开发过程中怎么应用. 提交+Push 如果本地开发代码有改动了或者你觉得某功能做完了,你打算把改动代码提交到远程仓库,这个时候很简单, 还是在工具栏 ...
- 电子钱包的圈存——java card开发第四篇
隔了好久没更新了,前一篇创建好了文件系统,那现在就可以实现使用电子钱包了,这篇首先讲电子钱包的圈存,其实就是存款进去的意思. 首先看一个灰常重要的流程图: 首先,终端(连着主机,他们的另一边是卡片)给 ...
- MFC开发IM-第四篇、mfc 对话框dialog的属性意思
在上一讲中介绍了MFC的消息映射机制,属于原理方面的知识.对于VC++编程入门学习者来说可能有些抽象,本文会把消息映射的知识渗透到后面的教程中.本节开始为大家讲解偏应用的知识-创建对话框. 对话框,大 ...
- 项目实训----Unity多人游戏开发----第四篇
游戏制作之人物移动(二) 综述 主体 内容2:人物移动控制方式--鼠标控制 总结 综述 上次我们主要进行讲解的是游戏开发过程遇到的一些问题,以及想法,主要讲述了如何使用键盘进行控制人物移动.主要是通过 ...
- Android UI开发第四篇——实现像handcent sms或者chomp sms那样的气泡短信样式
今晚有点时间把断了很长时间的UI开发补一下,这次实现的是像handcent sms或者chomp sms那样的气泡短信样式,也是iphone上的气泡聊天模式.实现这种效果的重点是ListView的di ...
最新文章
- http://www.cnblogs.com/dolphin0520/p/3949310.html
- 3 域名正则_一个正则表达式怎么会引起线上CPU狂飙?
- 深度学习之基于卷积神经网络实现超大Mnist数据集识别
- thinkphp python_ThinkPhp 5.0 服务器搭建问题总结
- Java并发包基石-AQS详解
- 华为给力!算力最强AI处理器在中国!
- 东哥再见!我打算 6 月份离职
- 简单使用SimpleCursorAdapter
- ROS机器人操作系统——ROS介绍
- 【数据库设计及SQL代码实现】英皇电影院电影管理系统
- 【笔记】C++之SLT的常用容器
- TapTap 发布开发者服务:降低开发者研运成本 聚焦创作优质内容
- 计算机存储单位的换算关系
- html扇形展开,css如何画扇形?
- 我以为自己MySQL够牛逼了,直到被腾讯面试官狠狠抽了两巴掌
- HNUCM—第14届蓝桥杯CC++组选拔赛
- 工作面试:工作交接(5)
- Elasticsearch:使用反向地理编码在地图上显示自定义区域统计数据
- 不为人知的地下暗流:揭秘色情推广“影科技”家族背后的流量生意
- 基于AT89S51的单片机无线双显示抢答器
热门文章
- oracle24550,ORA-24550: signal received:这个问题的原因及解决办法
- eclipse你的主机中的软件中止了一个已建立的连接。_如何备份/恢复一个基于Windows系统的操作面板?...
- java序列化原理_Java序列化机制和原理
- idea jstl需要导包吗_1,IDEA-安装及全局配置
- aix 查看防火墙状态_aix防火墙怎么样设置
- 命名实体识别_命名实体识别的几种标注形式
- Vue的批量更新原理
- 快速搭建centos7
- linux centos 安装rar,CentOS6.8 安装rar解压缩
- 使用双向链表构建二叉树_python:26.二叉搜索树与双向链表