在玩转数据模型的过程中,你是不是也被这些小烦恼缠上啦:

计算列到底是个啥?计算度量又是什么神秘 “物种”?

计算列和计算度量之间,到底藏着什么不同的小秘密?

碰到具体问题时,该怎么挑计算列和计算度量呢?


首先,计算列、计算度量的存在,主要是辅助我们在创建模型时更好的进行二次计算,那先来说说为啥要二次计算?打个比方,数据源就像一个食材库,可有时候,里面缺了咱们做菜(分析数据)要用的食材,这时候就得自己动手加工一下,比如把数据 “切一切”(分割)、给字段类型 “换换装”(转换),或者求个平均值、找同期值啥的。

注意,这里有个关键的知识点要划重点啦!与报表层面进行二次计算不一样的是,模型定义是全局二次计算,也即我们在数据模型层面定义了一个计算逻辑,它就能在多个报表或多个组件复用。

 

下面就让我们一个个来揭开计算列、计算度量它们背后的神秘面纱吧!

两者的含义、作用、创建方式对比详情见下表:

分类

计算列

计算度量

定义

在表中新增列,每行值由自定义公式生成

在多维数据集(OLAP)中通过 MDX 表达式定义,基于已有度量进行二次计算

计算顺序

基于表中现有字段列,逐行计算,先于汇总操作

基于已有的度量值,先汇总数据,再基于汇总结果计算

作用层级

表结构层面,新增列成为表的一部分,作用于数据表内每行数据

度量层面,基于现有度量进一步运算,属于跨维度聚合数据(如按时间、产品类别汇总后计算)

创建入口

数据模型右侧维度区 “+” 号 或 仪表盘报表开发界面的数据维度区 “+” 号

数据模型右侧度量区 “+” 号 或 仪表盘报表开发界面的数据维度区 “+” 号

创建方式

直接进入编辑界面,手动编写表达式(支持字段选择和函数拖拽)

两种方式:

1. 向导式(内置时间计算、数学运算等模板,支持拖拽字段快速创建);
2. 复杂方式(手动编写 MDX 函数,支持函数搜索和示例参考)

支持函数

使用数据库函数或平台内置函数(如数值、文本、日期处理函数)

除了内置函数(含时间计算、聚合函数、逻辑判断等),还支持调用 MDX 的函数,官方文档:https://mondrian.pentaho.com/documentation/mdx.php


由于两者创建方式和计算方式略有不同,最终操作步骤和对应得出的结果也会有所差异,详情如下:

(1)新建计算列,字段皆来自于表字段

                                  在数据模型右侧维度区右上方“+”号或仪表盘报表开发界面的数据维度区右上方“+”号入口都可以新建计算列使用,如图:

(2)新建计算度量

                                     在数据模型右侧度量区右上方“+”号或仪表盘报表开发界面的数据维度区右上方“+”号入口都可以新建计算度量使用,如下图:

     

          方式(1)向导方式:简单选择进行快速计算 : 实现同期、前期、累计值等,此页签界面主要是提供内置的数学运算、时间计算以及其他计算类型,也即可通过简单的拖拽操作快速创建所需的计算度量,如下图:

方式(2)函数方式:使用mdx函数来实现各种复杂场景下的高级计算,可看到右侧边栏很多内置函数,点击函数可看左下方的说明和示例;

(3)创建报表,拖拽计算列和计算度量对比结果:

查看系统监控——SQL/MDX监控,涉及的区域和销售额计算列都是从业务数据源通过SQL查询,并且销售额计算列是在原表直接处理,然后和其他表字段一并输出:

查看系统监控——SQL/MDX监控,涉及的区域是从业务数据源通过SQL查询,但是销售额计算度量是在对原表数据分类汇总处理后,再基于汇总结果也即对已有的度量进一步计算处理:


同样,查看系统监控——SQL/MDX监控,涉及的区域和销售额计算列都从业务数据源通过SQL查询,并且销售额计算列是在原表直接处理,但与维度区普通销售额计算列不同的是,销售额计算列-对应的度量会进行多一层sum的汇总计算,然后再和其他表字段一并输出:



学习计算列和计算度量两者含义、作用、创建方式和对应结算结果差异后,我们继续来看看两者的应用场景有何区别?

常用应用场景对比说明如下表:

说明

场景说明

相同之处

(1)均支持数值计算、逻辑判断、日期处理等基础功能;
(2)均可通过自定义公式或函数扩展数据处理能力;
(3)均支持对原始数据进行分类、逻辑判断等。

计算列-
常用场景

转换数据格式、转换数据类型、或取整:

把数值或者日期转换成字符串,使用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判断处理;


接下来,让我们继续走进不同场景的实际示例,就像玩解谜游戏一样,看看在什么情况下,计算列是最佳 “搭档”,而什么时候计算度量又能 “大显身手”。多研究几个实际案例,就像多积累了几个通关秘籍,帮你透彻理解如何选用计算列和计算度量,保准让你豁然开朗!

(1)场景描述:计算两数值字段相乘,需要计算前判断若字段为空则显示0

预览结果:

(2)场景描述:值判断是否为空,数据源中存储的数据有null,需要判断最终展示的结果数据 为 null时 显示为 0 

预览结果:

 

(3)场景描述:把订单模型订单表中的“区域”、“省份”、“城市”、“地址”这几个字段拼接成一个收货地址

预览结果:

 

(4)场景描述:需把指定成员拼接成一个字符串,例如如何把销售额前3的3个城市名称拼接成一个字符串显示

预览结果:

(5)场景描述:有一个“订单日期”字段,把它作为筛选器,当前值是2024年7月11,现在要取这个日期的前30天

 


预览结果:

(6)场景描述:返回日期之间的天数差,比如计算下单到发货用了多久

 

预览结果:


(7)场景描述:查询购买商品次数大于1的客户数有多少

预览结果:

(8)场景描述:如何计算某些成员的销量,例如计算“产品名称”下的白米的销量

揭晓答案:

【推荐】方案一:如果计算度量只有指定成员汇总,可以优先使用计算列,计算结果通过计算列处理好再复制转度量使用计算列转度量走SQL引擎优化查询性能较好

【不推荐】方案二:接通过计算度量向导——计算类型选择“按指定成员集聚合度量”并勾选“白米”作为成员集。


预览结果:

 

(9)场景描述:如何排除某些成员的指标,例如排除产品类别为点心的销售额?

注意:选维度成员下面的【产品类别】,上面维度那个包含了一个all成员,数据会翻倍;

预览结果:

(10)场景描述:按多个维度指定成员进行过滤汇总,例如计算2020年、东北区域、点心类别的销售额

注意:如果要更多个维度,可以再嵌套一个NONEMPTYCROSSJOIN,用多了NONEMPTYCROSSJOIN 可能会存在性能问题。

预览结果:

 

(11)场景描述:指定维度进行汇总,例如需查询【区域】和【类别】的销售额合计值,但是又想显示区域的销售额与它进行对比

预览结果:

 

(12)场景描述:报表查询涉及时间层次,勾选字段最小粒度到年月日,但是希望或者月份层次的度量前期值,如何处理?

预览结果:

 

(13)场景描述:仪表盘进度图组件需要获取度量数据里的最大值作为目标值, 例如降序的话第一个一直的100%的效果,如何处理

注意:像示例(9)选维度成员下面的【发货区域】,上面维度那个包含了一个all成员,数据会翻倍;

预览结果:

(14)场景描述:动态获取往月的月末值和当前月前一天值, 例如根据月份筛选器判断,往期拿当月最后一天的值,本月拿前一天的值,如何处理

image-2024-10-25-14-35-39-717.png

预览结果:

(15)场景描述:希望计算去除某个维度影响的标准差值, 例如排除发货区域这个维度影响,计算产品类别对应的销售额标准差值,如何处理?

预览结果:

(16)场景描述:计算对应所选时间对应的去年年末度量值, 例如根据维度年月判断,获取去年年末的值作为业务的年初结果使用,如何处理

预览结果:

(17)场景描述:计算多维度的度量百分比排名, 例如发货机构华北里面有8个产品类别分组,希望计算点心产品组内数量排名第三,就是(8+1-3)/8*100&=75%,如何处理

预览结果:

此示例比较复杂,附上资源:百分比排名测试资源.xml


优先选择计算列或计算度量的场景决策树:

1、是否需要聚合?

是 → 计算度量(如场景2、4、7、8、9、10、11)

否 → 计算列(如场景1、3、5、6)

2、是否需要动态上下文?

是 → 计算度量(如结果依赖维度和度量聚合后的数据)

否 → 计算列(如结果仅依赖原始数据)

3、是否涉及成员筛选?

是 → 计算度量(如场景8、9、10)

否 → 根据其他条件判断。

典型错误规避:


在本篇文章中,我们继续结合具体案例演示了计算列和计算度量两者在计算逻辑方面的特性,相信我们遇到不同业务场景需求时,都会快速定位应选用计算列还是计算度量,确保业务展示结果正确性啦!

当你掌握了这些核心技能,就能像数据魔法师一样灵活驾驭数据模型。那么最后一个问题来了 —— 如何正确使用数据模型参数?别急,这正是我们下篇要解锁的终极秘籍!