如何在 DAX 中创建 “虚拟关系”


各位小伙伴周三好,今天工坊为大家带来的是如何在DAX中创建“虚拟关系”。
七夕很快就要到了,希望大家了解这三个创建“虚拟关系”的函数之后,马上可以和TA建立起关系~

引用“非活动物理关系”

在建立模型关系时,有时候会无法建立“活动”关系。比如以下情况:
file

首先建立【注册人数】度量值:

注册人数 = DISTINCTCOUNT('客户表'[客户名称])

此时时间表是无法筛选当日的注册人数的。
file

'时间表' 和 '客户表' 间无法创建“活动”关系,因为会造成多义性。
即时间表会存在两条关系控制’销售表’:
时间表——销售表
时间表——客户表——销售表

这在Power BI中是不允许出现的。
file

这个时候,我们往往会通过 USERELATIONSHIP (引用关系)函数来引用“非活动”关系。

Userelationship_注册人数 =
CALCULATE ( [注册人数], USERELATIONSHIP ( '时间表'[日期], '客户表'[注册时间] ) )

结果如下,可以实现通过时间表筛选当日的注册人数:
file

当两表无法构建物理关系的时候,我们还有没有其他办法实现筛选控制呢?
答案是有的。那就是通过构建“虚拟连接”来实现行上下文的筛选。
可以达到目的的DAX函数有三个,分别是:
1、TREATAS
2、CONTAINS
3、INTERSECT

TREATAS 函数
file

将表达式返回的结果作为过滤器应用于不相关的表中的列,这样看来它一定常和CALCULATE连用。
我们通过TREATAS函数构建时间表和客户表之间的虚拟连接来实现日期控制注册人数。

Treatas_注册人数 =
CALCULATE ( [注册人数], TREATAS ( VALUES ('时间表'[日期] ), '客户表'[注册时间] ) )

它可以把本表‘客户表’指定列【注册时间】的筛选上下文属性传递至目标表‘时间表’,这样目标表‘时间表’可以获得对应的筛选能力。结果如下:

file

CONTAINS 函数

file

CONTAINS意思是包含,且CONTAINS是一个逻辑判断函数,返回值为TRUE或FALSE。
理解起来就是,前两个参数

Contains_注册人数 =
CALCULATE (
    [注册人数],
    FILTER (
        ALL ( '客户表'[注册时间] ),
        CONTAINS ( VALUES ( '时间表'[日期] ), '时间表'[日期], '客户表'[注册时间] )
    )
)

FILTER(ALL('客户表'[注册时间]),筛选出了所有CONTAINS判定为真的值,也就是时间表中日期为注册时间的值。
file

INTERSECT 函数

file

返回以左表为主表的两个表的行交集,保留重复项。
返回结果可直接作为筛选器。
INTERSECT理解起来比较容易,返回以左表为主的两表交集,然后通过交集筛选主表。

Intersect_注册人数 =
CALCULATE ( [注册人数], INTERSECT ( ALL ('客户表'[注册时间] ), VALUES ( '时间表'[日期] ) ) )

结果同样可以通过副表'时间表'完成对'客户表'的行上下文的筛选:
file

虚拟关系和物理关系的区别

当模型完全不存在物理关系时,我们依然可以通过虚拟关系来完成行上下文筛选的功能。
我们删掉之前创建的所有物理关系:

file

可以看到靠引用物理关系的USERELATIONSHIP会失效,虚拟关系则依然生效。

“虚拟连接”DAX函数的适用条件

  • 两表出现多对多或者关系冲突,无法直接建立关联;
  • 维度表和事实表之间没有可以单独关联的列;
  • 数据模型非常复杂时,通过建立虚拟连接减少表格之间物理连接的依赖;
  • 最后连接得出的筛选器是两表的交集,也就是以数据较少的表为进行筛选。

今天的内容就到这里,小伙伴们下期再见!

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

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


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

Power Pivot工坊