在玩转数据模型的过程中,你是不是也被这些小烦恼缠上啦:
计算列到底是个啥?计算度量又是什么神秘 “物种”?
计算列和计算度量之间,到底藏着什么不同的小秘密?
碰到具体问题时,该怎么挑计算列和计算度量呢?
首先,计算列、计算度量的存在,主要是辅助我们在创建模型时更好的进行二次计算,那先来说说为啥要二次计算?打个比方,数据源就像一个食材库,可有时候,里面缺了咱们做菜(分析数据)要用的食材,这时候就得自己动手加工一下,比如把数据 “切一切”(分割)、给字段类型 “换换装”(转换),或者求个平均值、找同期值啥的。
注意,这里有个关键的知识点要划重点啦!与报表层面进行二次计算不一样的是,模型定义是全局二次计算,也即我们在数据模型层面定义了一个计算逻辑,它就能在多个报表或多个组件复用。
下面就让我们一个个来揭开计算列、计算度量它们背后的神秘面纱吧!
分类 | 计算列 | 计算度量 |
定义 | 在表中新增列,每行值由自定义公式生成 | 在多维数据集(OLAP)中通过 MDX 表达式定义,基于已有度量进行二次计算 |
计算顺序 | 基于表中现有字段列,逐行计算,先于汇总操作 | 基于已有的度量值,先汇总数据,再基于汇总结果计算 |
作用层级 | 表结构层面,新增列成为表的一部分,作用于数据表内每行数据 | 度量层面,基于现有度量进一步运算,属于跨维度聚合数据(如按时间、产品类别汇总后计算) |
创建入口 | 数据模型右侧维度区 “+” 号 或 仪表盘报表开发界面的数据维度区 “+” 号 | 数据模型右侧度量区 “+” 号 或 仪表盘报表开发界面的数据维度区 “+” 号 |
创建方式 | 直接进入编辑界面,手动编写表达式(支持字段选择和函数拖拽) | 两种方式: 1. 向导式(内置时间计算、数学运算等模板,支持拖拽字段快速创建); |
支持函数 | 使用数据库函数或平台内置函数(如数值、文本、日期处理函数) | 除了内置函数(含时间计算、聚合函数、逻辑判断等),还支持调用 MDX 的函数,官方文档:https://mondrian.pentaho.com/documentation/mdx.php |
由于两者创建方式和计算方式略有不同,最终操作步骤和对应得出的结果也会有所差异,详情如下:
(1)新建计算列,字段皆来自于表字段
在数据模型右侧维度区右上方“+”号或仪表盘报表开发界面的数据维度区右上方“+”号入口都可以新建计算列使用,如图:
新建计算列:在这个界面中,有表达式编辑框、字段选择栏以及选择函数使用栏,可以根据实际需求,利用这些功能进行相关定义:
(2)新建计算度量
在数据模型右侧度量区右上方“+”号或仪表盘报表开发界面的数据维度区右上方“+”号入口都可以新建计算度量使用,如下图:
新建计算度量:
方式(1)向导方式:简单选择进行快速计算 : 实现同期、前期、累计值等,此页签界面主要是提供内置的数学运算、时间计算以及其他计算类型,也即可通过简单的拖拽操作快速创建所需的计算度量,如下图:
方式(2)函数方式:使用mdx函数来实现各种复杂场景下的高级计算,可看到右侧边栏很多内置函数,点击函数可看左下方的说明和示例;
查看系统监控——SQL/MDX监控,涉及的区域和销售额计算列都是从业务数据源通过SQL查询,并且销售额计算列是在原表直接处理,然后和其他表字段一并输出:
查看系统监控——SQL/MDX监控,涉及的区域是从业务数据源通过SQL查询,但是销售额计算度量是在对原表数据分类汇总处理后,再基于汇总结果也即对已有的度量进一步计算处理:
同样,查看系统监控——SQL/MDX监控,涉及的区域和销售额计算列都从业务数据源通过SQL查询,并且销售额计算列是在原表直接处理,但与维度区普通销售额计算列不同的是,销售额计算列-对应的度量会进行多一层sum的汇总计算,然后再和其他表字段一并输出:
学习计算列和计算度量两者含义、作用、创建方式和对应结算结果差异后,我们继续来看看两者的应用场景有何区别?
说明 | 场景说明 | |
相同之处 | (1)均支持数值计算、逻辑判断、日期处理等基础功能; | |
计算列- | 转换数据格式、转换数据类型、或取整: | |
把数值或者日期转换成字符串,使用TOSTR函数; | ||
将时间戳转换成日期格式,使用UNIXTIMETODATE函数; | ||
将字符串类型数据格式转换成日期格式,使用STRTODATE函数; | ||
对字段取整,使用TOINTEGER函数; | ||
求明细数据对应某个日期前X天/年/月/季或日期时间差值等的日期时间计算: | ||
获取当年第一天,可以通过YEAR函数获取当前年,再用CONCAT函数进行拼接; | ||
返回日期之间的天数差,使用DATEDIFF函数; | ||
对原始数据分类判断使用: | ||
对原始数据分类使用IIF函数判断; | ||
对数据表数据的值进行case when判断再应用,可以使用计算列构造出是否 | ||
计算度量- | 对度量做复杂计算,方差、中位数等: | |
求销售收入的期末值,Tail函数和filter函数结合处理; | ||
求销售额的年方差,使用VAR函数; | ||
查询各个产品类别销售额的中位数,使用Median函数; | ||
查询销售额的4次方根,使用Power函数; | ||
汇总计算: | ||
计算近两个月的销售额,使用AGGREGATE函数和ParallelPerodex函数结合处理; | ||
指定维度进行汇总,使用Fixed函数; | ||
按多个维度进行过滤汇总,aggregate函数和nonemptycrossjoin函数结合处理; | ||
对汇总数据排名、比较、分类处理: | ||
查询各个产品销售额的排名情况,使用rank函数; | ||
计算两个时间段的比值,使用AGGREGATE函数; | ||
对汇总后数据做判断,对度量进行case when判断处理; |
接下来,让我们继续走进不同场景的实际示例,就像玩解谜游戏一样,看看在什么情况下,计算列是最佳 “搭档”,而什么时候计算度量又能 “大显身手”。多研究几个实际案例,就像多积累了几个通关秘籍,帮你透彻理解如何选用计算列和计算度量,保准让你豁然开朗!
揭晓答案:对原始字段值直接判断处理,选用计算列,使用IFNULL 函数,当值为null时转成0,如果为””空时也可以转成0 :
预览结果:
揭晓答案:判断展示结果数据,那就是对度量判断处理,得选用计算度量二次计算判断,通过IIF函数、IsEmpty函数进行判断,如下图表达式的含义:如果[销售额]度量为空,则返回0,否则返回1。
预览结果:
揭晓答案:直接拼接表字段应该使用计算列哦,创建计算列,使用CONCAT函数进行拼接,可以使用无数个字段或者常量。
预览结果:
揭晓答案:与例子3)不一样的是,这个需求是需要判断度量汇总后的值,再拼接实际汇总对应结果值,此时应该选用计算度量,如下图:
预览结果:
揭晓答案:对表字段判断处理,应该选用计算列,通过DATEADD 函数实现:
预览结果:
揭晓答案:对明细行字段判断处理,应该选用计算列,通过DATEDIFF函数实现:
预览结果:
揭晓答案:需基于维度汇总后的度量进行二次计算分析,创建计算度量,使用count、Filter 函数实现:
预览结果:
揭晓答案:
【推荐】方案一:如果计算度量只有指定成员汇总,可以优先使用计算列,计算结果通过计算列处理好再复制转度量使用,计算列转度量走SQL引擎优化查询性能较好
【不推荐】方案二:接通过计算度量向导——计算类型选择“按指定成员集聚合度量”并勾选“白米”作为成员集。
新建计算列-复制转度量:
新建计算度量:
预览结果:
查看系统监控-SQL/MDX记录,可看到计算列转度量的查询耗时比直接计算度量处理快很多:
揭晓答案:涉及成员的可以新建计算度量,通过AGGRGATE、EXCEPT函数处理:
注意:选维度成员下面的【产品类别】,上面维度那个包含了一个all成员,数据会翻倍;
预览结果:
揭晓答案:涉及维度指定成员汇总处理,选用计算度量,通过AGGREGATE、NONEMPTYCROSSJOIN 函数实现;
注意:如果要更多个维度,可以再嵌套一个NONEMPTYCROSSJOIN,用多了NONEMPTYCROSSJOIN 可能会存在性能问题。
预览结果:
揭晓答案:涉及维度汇总处理,选用计算度量,通过FIXED函数实现;
预览结果:
揭晓答案:涉及时间层次汇总处理,选用计算度量,通过计算度量知道日期的CurrentMember.parent.PREVMEMBER值实现;
预览结果:
揭晓答案:可以新建计算度量,通过MAX函数获取到最大值,然后把目标值设置为这个最大值使用
注意:像示例(9)选维度成员下面的【发货区域】,上面维度那个包含了一个all成员,数据会翻倍;
预览结果:
揭晓答案:可以新建计算度量,结合模型参数值判断
预览结果:
揭晓答案:可以新建计算度量,使用STDEV和EXCLUDE函数判断处理
预览结果:
揭晓答案:可以新建计算度量,获取所选维度对应的CurrentMember.PARENT.PREVMEMBER.lastchild【找到当前成员-再找其父成员-接着找父成员同级的前一个成员-最后获取这个成员的最后一个子成员】值判断获取
预览结果:
揭晓答案:可以新建计算度量,其中分子就是维度层次按指定度量排序后再计算其排名生成的
预览结果:
此示例比较复杂,附上资源:百分比排名测试资源.xml
1、是否需要聚合?
是 → 计算度量(如场景2、4、7、8、9、10、11)
否 → 计算列(如场景1、3、5、6)
2、是否需要动态上下文?
是 → 计算度量(如结果依赖维度和度量聚合后的数据)
否 → 计算列(如结果仅依赖原始数据)
3、是否涉及成员筛选?
是 → 计算度量(如场景8、9、10)
否 → 根据其他条件判断。
在本篇文章中,我们继续结合具体案例演示了计算列和计算度量两者在计算逻辑方面的特性,相信我们遇到不同业务场景需求时,都会快速定位应选用计算列还是计算度量,确保业务展示结果正确性啦!
当你掌握了这些核心技能,就能像数据魔法师一样灵活驾驭数据模型。那么最后一个问题来了 —— 如何正确使用数据模型参数?别急,这正是我们下篇要解锁的终极秘籍!