前面,我在文章《​​DAX的核心,其实只有4个字!​​》里提到,DAX核心思想,就是“筛选、计算”四个字,当然,这个总结非常抽象,接下来,我会用一个又一个的例子来给大家具体讲,大家将慢慢体会到,几乎所有的度量都紧紧围绕这个思想而展开。


我们先看一个简单的例子:计算产品销售金额百分比,通过这个例子,体现“一个度量,是怎样炼成的”,即,写一个度量的主要思考过程。


Step-01 熟悉数据模型


首先,在动手写任何一个度量之前,必须清楚:我的数据模型(表及其关系)是怎样的?


比如,本例用罗斯文贸易示例数据模型(下载链接见文末),首先要知道:


  1. 模型里面都有哪些表?

  2. 每个表里都有哪些数据?

  3. 哪些表跟哪些表之间是1对多的关系?

  4. 表和表之间的筛选关系是怎样的?


一个度量,是怎样炼成的? | DAX重要思路_数据模型


一般来说,对于自己日常工作中的数据模型,应该要做到烂熟于胸,在这种情况下,自然直接跳过这一步。


但是,如果是向别人提问,那应该首先把自己的数据模型(按需要脱敏、简化后)发出,并描述清楚,否则,直接问别人一个度量该怎么写,那基本是没有办法回答的。


Step-02 理解度量使用环境


熟悉自己的数据模型后,还要充分理解自己所要写度量的使用环境,即想要的计算结果是怎样的?放在哪里用?


这里主要包含2个层面的内容:


1、计算结果放在哪里用?

2、计算结果将会受到哪些筛选条件(筛选/切片器、图表坐标轴或行列维度等等)的影响?


比如,本例中,我们计算一个简单的产品销售金额百分比,可能是要放到一个带产品列的数据表里,放在数量的后面;影响这个图表的筛选条件除了结果表本身的“产品名称”外,还有“类别名称”、“客户名称”、“月份”等等。


一个度量,是怎样炼成的? | DAX重要思路_数据模型_02


有的朋友说,我想要写一个通用的度量啊,不是说度量能放到哪里都能用吗?


实际上,没有所谓百分百通用的度量,只是大部分的度量,在不太特殊需求的情况下,能够适用于比较多常用的计算环境(报表)而已。


同时,事先想好这个度量的主要使用环境,并在具体的图表中把这种环境显示出来,对动手写度量非常有帮助!


此外,虽然结果是要计算占比,但首先应该先计算金额,然后再计算百分比,所以,这里到底是直接写1个度量计算百分比?还是2个?


就这个例子来说,显示百分比的同时,最好把金额也显示了,而且,金额这个度量,应该在很多地方都用得着,所以一般来说应该把金额单独出来,也就是说,我们要写的是2个度量(金额、金额占比),而不是1个。


Step-03 数据筛选与计算


熟悉了自己的数据模型情况,也理解了自己要计算的度量的计算环境,接下来要搞清楚的是:


1、我要计算的度量需要用到哪些数据?

2、这些数据从哪些表来?

3、这些数据在目前的数据模型以及计算环境下,能否自动筛选出来?

4、如果不能,是否能通过调整模型实现?或者要怎样人工调整筛选条件?


回到计算产品销售金额百分比这个具体例子,要写两个度量:金额和占比。

显然,这两个度量的计算需要用到订单明细表里的数量、单价和折扣这些数据。


一、自动筛选与计算


对于金额这个度量来说,基于目前的模型和筛选条件,每一个产品的金额计算所要用到的订单明细表里的数据,都能自动筛选出来,所以,我们是可以直接计算的。


一个度量,是怎样炼成的? | DAX重要思路_数据模型_03


既然能直接计算就简单了,直接写计算公式:


.金额 =
SUMX(
'订单明细',
'订单明细'[数量]*'订单明细'[单价]*(1-'订单明细'[折扣])
)


一个度量,是怎样炼成的? | DAX重要思路_数据_04


之所以说,数据模型的设计那么重要,就是因为,设计良好的数据模型,能使尽可能多的业务分析所需要的度量计算,都可以通过自动筛选来完成,避免了大量后面人为调整筛选的麻烦,也就不用写那么多复杂的度量。


所以,为什么深入学习DAX,《Power BI建模权威指南》也是必读书之一!



二、人为调整筛选与计算


对于占比来说,涉及到所有产品的总金额的问题,也就是说,在结果表的每一行里,都要计算所有产品的总金额,然而,在结果表的每一行里,自动筛选出来的数据却只是当前行产品下的数据,并不足以支持所有产品总金额的计算——这时,就涉及到人为调整筛选的问题。


在DAX里,大量的表函数、调节器函数,就是为了配合CALCULATE函数,从而实现模型无法自动化筛选情况下的筛选器调整(增加、修改、删除……)和计算。其实,《DAX权威指南》讲了那么多的函数、案例,重难点都是围绕这个核心问题在讲!



回到这个例子,要在当前行产品的情况下,怎样才能“筛选”得到所有产品的相关数据呢?显然,如果我们“删除”了图表中“产品名称”筛选器的影响,这样,在图表每一行筛选的数据将是所有产品数据。而要删除筛选器的影响,很简单,通过ALL函数即可。


一个度量,是怎样炼成的? | DAX重要思路_数据模型_05

注意,这个图表的“产品名称”来自于“产品”表,而不是“订单明细”,所以,注意用ALL函数时,引用的是【'产品'[产品名称]】列。


各产品金额和全部产品的总金额都计算出来后,再计算占比,就比较简单了:


一个度量,是怎样炼成的? | DAX重要思路_数据_06


以上,就是写一个度量的基本思考过程,当然,这个例子比较简单,也不完美,但是,这个基本思考过程,是我个人认为学习DAX最重要的思想。


一个度量,是怎样炼成的? | DAX重要思路_数据模型_07


再次具体化一点儿,每当要写一个相对复杂的度量时,我就先在Power BI的报表页面先建一个报表(或者在Excel里先建个透视表),把一些相关的维度放到报表里——建好度量的使用环境,然后一边对着报表想,当前这一行的内容,背后筛选出了什么样的数据?一边看着度量想,要做怎样的数据调整才能实现计算的目标?直到最终筛选出合适的数据,完成计算。


一个度量,是怎样炼成的? | DAX重要思路_筛选器_08


后面,我将结合更多的案例,紧紧围绕“筛选-计算”的核心思想,把写度量的具体思考过程写出来,希望为大家学习DAX提供一些参考。