之前的文章(采悟:连接表的几个DAX函数,一次全掌握)介绍了产品A的客户与产品B的客户的各种交叉关系,其中最常用的应该是找出A和B的共同客户,以便进行产品关联分析。

之前的思路是计算出两个产品的共同客户数,那么能不能选择三个产品呢,当然是可以的,利用上篇文章的思路,把三种产品的客户找出来,然后求三个表的交集就可以了。

但是这种方法是不是显得太笨拙了?如果只是两三个产品的共同客户数,勉强还可以使用,但如果是十几个甚至几十个产品,难道要先计算出几十个产品的客户表,再一个个求交集?

DAX当然不会这么笨,本文就给你看一个优雅的解决方案。


以关联分析中的示例数据为例(采悟:PowerBI分析模型:产品关联度分析),当时是利用一个切片和一个表格上下文的方式,来计算两种产品的共同客户数,

数据可视化之powerBI技巧(五)在Power BI中写出优雅的度量值是什么体验?-LMLPHP

下面这个度量值,可以返回任意产品组合的客户数量,

来看看它的效果,

数据可视化之powerBI技巧(五)在Power BI中写出优雅的度量值是什么体验?-LMLPHP

任意选择多个产品,都可以自动计算出共同客户的数量,这种方式是不是比之前的要优雅的多呢?

再回头看这个度量值的代码,并不长,比上一篇文章中的代码都要短一些,但其理解难度却比那些要高出几个等级。

其中最重要的一个函数就是GENERATE,它的参数很简单,就是两个表,但是封装了强大的计算逻辑。它的这两个参数表,并不是简单的单独计算出来以后再合并到一起。事实上它的第一个参数表的每一行,为第二个表的表达式提供行上下文,在每一行上分别计算第二个表的表达式。

并且这个度量值中,GENERATE的第二个参数的表表达式,其中又使用了VALUES函数和CALCULATETABLE函数,利用它们对行上下文不同的计算逻辑,来最终返回未购买全部所选商品的客户列表。

如果把GENERATE函数彻底弄懂了,你对DAX的掌握,对上下文的理解都可以提升一大步。

这里你如果实在看不懂,也可以先直接用着,回头再慢慢品味。

我整体上再简单解释一下这个度量值,

VAR定义的第一个表t1是最重要的一环,该表返回的是只有两列的表,客户ID和产品名称,每一行组合全是订单表不存在的组合(把t1逻辑搞懂了,你也就理解了这个度量值);

t2将t1表的客户ID提取出来,含义是至少未购买过其中一个所选商品的客户列表;

t3利用EXCEPT函数,剔除t2的客户,就是所选商品的共同客户列表;

最后利用COUNTROWS函数返回共同客户的数量。

是不是仍然很绕呢,不要指望几句话就能帮你理解这个代码,你需要动手去练习,观察它的输出结果,思考上下文的逻辑,这时可以再看一下这篇文章:如何快速理解一个复杂的DAX?

总结

看起来很长的DAX代码并不一定就很难理解,而短的也不一定就很简单。实现同样的业务逻辑,把DAX写的很长并不算很厉害,而知道如何把代码写短,更需要深厚的内功。

优雅的背后,是长期的积累。

05-19 16:11