PowerBI DAX 计算组 基础篇
随着 PowerBI 在2020.7月的发布,迎来一个重要的功能:计算组(Caculation Group)。
我们会用几个篇幅从基础到高级来给出计算组的所有使用方式和内幕,供大家使用。本文是基础篇。先玩起来再说。
那么本文就来带小伙伴手把手的使用这一强大特性:计算组。
计算组为何而生
很多人只学习已经存在之物,例如:
- 他知道 DAX 存在,所以学习 DAX,但不问 DAX 为何而生
- 他知道行上下文的存在,所以学习行上下文,但不问行上下文为何而生
- 他知道筛选上下文的存在,所以学习筛选上下文,但不问筛选上下文为何而生
- 他知道上下文转换,所以学习上下文转换,但不问上下文转换为何而生
- …
我们的最大不同的,需要思考一个事物,它为什么会存在,而不仅仅是存在的某个事物。
我们知道有很多度量值表示不同的指标,例如:销售额,利润,数量,毛利,成本,费用,人数,浏览数…
在一个标准的模型里,很容易就会出现几十个甚至上百的独立含义的度量值指标。
如果去编写和日期有关的逻辑,例如:某指标的去年同期,则有:
CALCULATE( [某指标] , DATEADD( Calendar[Date], -1, YEAR ) )
与此类似的逻辑有:去年同期,上月同期,同比增长,… 几十个逻辑。
在构建这些业务逻辑时,DAX 设计师很快就可以发现这里触犯软件工程界的一个禁忌:DRY原则(Don’t Repeat Yourself)。
这是不能被允许的。因此,就需要有一个机制来解决这个问题。
这个机制再明显不过了,那就是:
CALCULATE( [某指标] , DATEADD( Calendar[Date], -1, YEAR ) )
中的 [某指标] 只要可以被捕获到即可,DAX 设计者设计了 SELECTEDMEASURE ()
DAX 函数来实现这个特性。
也就是:
CALCULATE( SELECTEDMEASURE() , DATEADD( Calendar[Date], -1, YEAR ) )
结束。
这就为 去年同期 建立了一个逻辑。
同理,可以为其他内容建立逻辑,例如:
- AC - 当前逻辑
- PY - 去年同期
- YTD - 年度至今
- Growth% - 同比增长率
由于这些逻辑有一定的相关性,DAX 设计者将其编为一组,成为计算组(Calculation Group)。
要理解计算组,非常简单,这里强调两个点:
第一,对于某一个计算逻辑,它和正在计算的某指标发生碰撞,而该计算逻辑将进一步改变当前计算的某指标的逻辑。正如一个力量改变原来运动的实体的方向,那个运动的实体可能是人,石头,手机,砖头等(度量值)。
第二,对于一组相关的逻辑,可以编成一组,产生一种批发模式效应。
完。
在这个基础之上,存在一些细节的调整,例如:顺序,格式等。
下面给出在 PowerBI 中的实践方式。
开启 PowerBI 的增强元数据
确保下载了最新版的 PowerBI 桌面版。下载地址:
https://aka.ms/pbiSingleInstaller
在 PowerBI 的预览功能中开启:
这样,PowerBI 的所有内容将以一种新的模式存在,它是必须的,这是 PowerBI 的未来默认存储方式。(目前处于过渡期)
安装 TabularEditor
确保自己的计算机已经安装了 Tabular Editor 如下:
下载地址:
https://tabulareditor.com/
这个工具是完全开源免费的。只不过目前的界面没有支持中文,但是很简单。
PowerBI 外部工具
安装刚才的步骤安装好以后,一般可以看到:
如果出现问题,可以参考下文来排查修复:
这里提及 PowerBI 外部工具仅仅是作为文章的完整性,即使您不考虑这个地方也完全不影响本文所说的实验。
为什么非要 Tabular Editor
很多伙伴问一个问题:这不是 PowerBI 吗?为什么要用另外的软件来编辑呢?
由于历史原因,PowerBI Desktop 要兼顾很多事情,包括可视化等问题。它就像一个可以操控 DAX 引擎的壳子一样。实际的问题是:
DAX 引擎升级了,PowerBI Desktop 壳子还没有对应部分的升级怎么办?
这样,我们可能就无法透过 PowerBI Desktop 来操作 DAX 引擎。
Tabular Editor 轻装上阵,它就是面向 DAX 引擎的定义文件的快速编辑器。所以,对 DAX 引擎的很多快速编辑和批量修改在 Tabular Editor 里进行总是几乎可以操控 DAX 引擎的最新特性。
但最后,我们相信 PowerBI Desktop 也会给出类似操作途径,只不过还需要等待。
从 Tabular Editor 开始
打开,如下:
点击:
选择正在运行的 PowerBI Desktop,如下:
请注意:
- PowerBI Desktop 必须提前运行起来
- PowerBI Desktop 必须已经有一个数据模型而不能是空的
建议:
可以在运行 Tabular Editor 之前,现在 PowerBI Desktop 中构建一个简单的模型来做这个实验。
选择,并点击“OK”,即可。如下:
我们可以在 Tabular Editor 里做很多事,这里暂且不表,后续文章再做介绍。
新建计算组
右键点击“Model”,弹出:
这就是:计算组。
点击创建一个计算组,如下:
创建的计算组必须是如上结构,里面包括:
- New Caculation Group
- Calculation Items
- Name
- Ordinal
这样的结构。
如果您的结构不是这样的,则说明有问题,请检查:
- PowerBI是否是最新版
- TabularEditor是否是最新版
- 重新安装他们并重新实验
效果定义
我们现在遐想一下,我们需要的效果,如下:
这里需要注意的是:
- AC,PY,Growth%,YTD 四种逻辑
- AC,PY,YTD 的格式是用“,”分隔的整数,而Growth%的格式是百分比
- AC,PY,Growth%,YTD 的排序位置
定义计算组
定义新建计算组的名字,如下:
而其中的 Name 也没有被赋予更加贴切的名字,将其修改如下:
接下来就可以定义具体的四个计算逻辑了:AC,PY,Growth%,YTD 四种逻辑。
定义计算组中的项
右键 Calculation Items,弹出:
建立名为 AC 的计算项,如下:
同样,再建立名为 PY 的计算项,如下:
通过建立两个计算项,可以看到:
- 图表带有问号,表示该内容并未保存到 DAX 引擎。
- Ordinal 指定了排序。
- Format String Expression 指定了格式化的字符串。 “#,#”表示用“,”表示千分位分隔符。
同样道理再创建名为 Growth% 的计算项,如下:
以及创建名为 YTD 的计算项,如下:
这样就创建完毕。
将更改保存至 DAX 引擎
将鼠标移动到这些新建立的项目上,可以看到:
含义是:表达式已经改变,需要发布。
点击:
含义是:将更改保存至已经连接的数据库(也就是 DAX 引擎)。
保存完,回到 PowerBI Desktop 可以看到:
只需要单独对其刷新即可,如下:
完成。
最终效果
按照下图拖拽出需要的矩阵,如下:
可以看出,这就实现了我们预期的效果。
值得强调的是:
这里的在矩阵的值,只放置了一个度量值。而按照预先定义的四个计算逻辑进行了计算。
- AC - 当前逻辑,不发生改变。
- PY - 去年同期
- Growh% - 同比增长率,格式为%。
- YTD - 年度至今
这就实现了最终的效果。
到底发生了什么
可以通过性能面板来观察,如下:
将这个内容复制到 DAX Studio 中查看,如下:
以及:
可以看到其实这里完成了两个对 DAX 引擎的查询,
- 第一个返回了排序规则,这与我们当时建立的规则一致。
- 第二个返回了实际数据。 数据中包括了格式化字符串用来指定数据的格式。
计算组的应用
计算组不仅仅可以用来做矩阵,还可以用来给用户提供一种新的选择,例如:
也就是说,计算组的字段可以为当成选项使用,这样可以给用户提供大量的计算逻辑。
也就是说,传统的切片器提供了参数的选择;而计算组提供了计算逻辑的选择。
总结
计算组,就是将一批相关逻辑定义在一起,成为一个分组,并施加给某个正在运算的指标,以产生批量的计算效果。
这就是基础应用。
在此基础上,还会扩展出更多复杂的情况,我们后续讨论。例如:如果一个指标碰上了多个计算组,怎么办。我们随后再来描述。
- Golang 值得注意的地方
- MySQL数值类型在binlog中需要注意的细节(r12笔记第69天)
- WordPress评论滑动/拉链解锁myQaptcha修改为自动提交的方法
- MySQL root用户登录的几个小问题(r12笔记第67天)
- Java实现生产者消费者的两种方式(r12笔记第66天)
- Golang语言的函数调用信息
- mysqldump的一点使用总结(r12笔记第81天)
- 转-Golang语言Interface漫谈
- WordPress导航菜单图标字体插件font awesome 4 menus纯代码版
- Oracle 12c远程克隆PDB的问题及修复(r12笔记第78天)
- Oracle表中含有255列以上时需要注意的(r12笔记第77天)
- Golang语言--资源自动回收技术
- Oracle 12.2中的一个参数说明(r12笔记第76天)
- Golang语言社区--【游戏服务器知识】多线程并发
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Apache Atlas 安装部署
- SwiftUI:禁止用户交互
- Qt音视频开发34-Onvif时间设置
- 网络工程师提高篇 | 路由重发布你了解多少?从原理到配置,瑞哥带你学习一波!
- 短视频APP开发,简单计时功能
- LeetCode | 94.二叉树的中序遍历
- Druid 的整合
- LeetCode | 104.二叉树的最大深度
- Flutter 目录结构和项目资源
- iOS音视频接入- TRTC互动直播
- 【一天一大 lee】查找常用字符 (难度:简单) - Day20201014
- 金九银十准备换场地?对标腾讯T3的Android高级工程师面试大纲及时雨来了
- 【一天一大 lee】两两交换链表中的节点 (难度:中等) - Day20201013
- 【一天一大 lee】二叉搜索树的最小绝对差 (难度:简单) - Day20201012
- 有奖互动 | 腾讯云开发者社区 3 周年庆,我过生日,送你们礼物 ~