DAX 实战 | 一个案例带你了解 CROSSFILTER


小伙伴们好啊~

今天带大家了解的函数是CROSSFILTER,一起来看下数据模型:
file

在我们的模型中提供了三张表:一张事实表:Sales;两张维度表:Customer和Date,分别用CustomerKey/Date和Sales建立一对多关系。

我们要解决的业务场景是:每一年有多少个城市(Customer表中每个客户对应的City字段)产生了销售

首先写一个基础度量:

NumberOfCities = DISTINCTCOUNT( Customer[City] )

file

可以看到,在我们的Customer表中有473个城市。如果我们直接用Date表里的年份和该度量拖出一个矩阵,得到的结果如下:
file

该结果源于以下事实:

在数据模型中,一端的筛选可以流向多端,而多端的筛选无法流向一端。

Date处于一端,筛选流向了多端的Sales。而Sales和Customer是多对一关系,Sales将不再筛选Customer,所以最终的结果是所有城市的数量。

应对该问题的一个简单方案是这样的:
file

将Customer和Sales之间的关系改为双向,Date的筛选就可以通过Sales流向Customer了。回到报表页面,再来看下结果:
file

将筛选器方向由单向改为双向改变了数据模型结构,在复杂的数据模型中使用双向筛选有引发歧义的风险。

在不修改原有模型结构的前提下,有没有办法计算出我们想要的结果呢?一起来看下CROSSFILTER的实现方式:

NumberOfCitiesWithSales =
CALCULATE (
    [NumberOfCities],
    CROSSFILTER ( Customer[CustomerKey], Sales[CustomerKey], BOTH )
)

CROSSFILTER语法如下:

CROSSFILTER(<columnName1>, <columnName2>, <direction>)

该函数有三个参数:前两个参数是建立了物理关系的字段;三参指定筛选的方向,分别是None,Oneway和Both。

这里我们使用Both,将原来的单向关系通过代码修改成双向,得到了上图一样的结果。

和建立物理双向关系的一个重要区别在于,用代码实现的双向筛选仅在当前度量值生效。如果您需要知道每一年有多少个国家产生了销售,则需要再次使用CROSSFILTER。

当然,如果您熟悉扩展表的概念,您也可以把中间的事实表当成桥表(Bridge Table),代码如下:

NumberOfCitiesWithSales v2 =
CALCULATE ( [NumberOfCities], CALCULATETABLE ( Sales ) )

再来看下对比:

file

细心的小伙伴会发现,两个度量在每一年计算的结果是一致的,但总计行两个度量值结果并不一致。

事实上,v2总计行计算的是正确的结果,前者的总计行则包括了未产生销售的城市,也就是Customer表中所有城市的数量。

聪明的小伙伴,你们能想到原因吗,欢迎踊跃留言~

今天的函数分享就到这里,下期再见~

  • PowerPivot工坊原创文章,转载请注明出处!

    如果您想深入学习微软Power BI,欢迎登录网易云课堂试听学习我们的“从Excel到Power BI数据分析可视化”系列课程。或者关注我们的公众号(PowerPivot工坊)后猛戳”在线学习”。


长按下方二维码关注“Power Pivot工坊”获取更多微软Power BI、PowerPivot相关文章、资讯,欢迎小伙伴儿们转发分享~

Power Pivot工坊