在Power BI中,模型的关系是数据建模的基础,这些关系决定了不同表之间如何相互连接和交互。
在这篇博客文章中,我将详细介绍三种关系:实线关系、虚线关系和虚拟关系,并解释它们的异同。
最后,我将探讨如何使用 USERELATIONSHIP 和 TREATAS 函数来处理这些关系。
1:X-MIND 思维导图
2:三大关系
2.1 实线关系 (Active Relationship)
实线关系是模型中默认的关系类型,它代表了两个表之间的主键和外键连接。这种关系通常用于计算和聚合数据。例如,销售表和日期表之间的关系。 特点:- 默认情况下,实线关系是激活的,意味着Power BI在计算时会优先使用这种关系。
- 一个表可以有多条关系,但同时只能有一条实线关系。
- 当你需要在一个模型中显示一个事实和一个维度之间的明确连接时。
2.2 虚线关系 (Inactive Relationship)
虚线关系在模型中也是表和表之间的连接,但它们默认是非激活的。这些关系通常作为备用连接,当需要时可以激活。 特点:- 虚线关系需要通过 USERELATIONSHIP 函数在特定度量值或计算中激活。
- 一个表可以有多条虚线关系,这提供了灵活性,允许在不同的情况下使用不同的连接。
- 当同一组表之间有多种可能的关系时,比如有多个日期字段(订单日期、发货日期等)需要使用不同的时间分析。
2.3 虚拟关系 (Virtual Relationship)
虚拟关系不是通过模型中的物理连接实现的,而是通过 TREATAS 函数在DAX计算中临时创建的关系。这种关系特别有用,因为它允许创建动态的连接,而无需在模型中创建额外的关系。 特点:- 虚拟关系在DAX代码中动态创建,不会显示在模型图中。
- 提供了极大的灵活性,可以在不改变模型结构的情况下进行复杂的数据分析。
- 当你需要在度量值中引用一个表的列,并将其与另一个表的列进行对比时
3: 关系函数
3.1 USERELATIONSHIP函数(虚线关系)
USERELATIONSHIP 函数用于在度量值中激活一个虚线关系。 这使得在一个计算中,虚线关系可以暂时作为实线关系来使用。DAX EXPRESSION示例: 假设我们有一个销售表和两个日期字段(订单日期和发货日期)。我们希望在一个度量值中使用发货日期而不是订单日期: Sales By Ship Date = CALCULATE( SUM(Sales[Amount]), USERELATIONSHIP(Sales[ShipDate], Calendar[Date]) )
USERELATIONSHIP(columnName1, columnName2)
3.2 TREATAS函数(虚拟关系)
TREATAS 函数用于在DAX表达式中创建虚拟关系。
它将一个表的列“投射”到另一个表的列上,从而创建一个临时的、基于值的关系。
TREATAS(columnName1, columnName2)
示例: 假设我们有一个产品表和一个销售表,我们希望根据产品类别进行聚合,但它们之间没有直接的关系:
Sales by Product Category = CALCULATE( SUM(Sales[Amount]), TREATAS( VALUES(Product[Category]), Sales[Category] ) )
这里解释一下,“投射”概念
在数据建模和DAX计算中,“投射”(Projection)指的是将一个表中的某些列的值,转换为另一个表中对应列的上下文,从而在不显式创建关系的情况下建立临时连接。TREATAS
函数就是用于实现这种投射的关键工具。
3.2.1 投射的过程
当我们使用 TREATAS
函数时,我们实际上是在说:“将这个表的这些列的值视为另一个表中这些列的值,并在计算中应用这个上下文。” 通过这种方式,我们能够在不改变模型结构的前提下,动态地创建关系,从而实现复杂的数据分析。
3.2.2 使用 TREATAS
实现投射的详细示例
假设我们有两个表:Product
表和 Sales
表。Product
表包含产品的类别,而 Sales
表包含销售记录及其对应的产品类别。我们希望根据产品类别聚合销售金额,但这两个表之间没有直接的关系。
这是我们使用上面的代码,解释一下:
Sales by Product Category = CALCULATE( SUM(Sales[Amount]), TREATAS( VALUES(Product[Category]), Sales[Category] ) )
解释代码
VALUES(Product[Category]):
这个部分获取 Product
表中 Category
列的唯一值。VALUES
函数返回一个包含这些唯一值的表。
TREATAS(VALUES(Product[Category]), Sales[Category]):
TREATAS
函数将 Product[Category]
列中的值投射到 Sales[Category]
列上。换句话说,它告诉Power BI,在计算上下文中,把 Product
表的类别视为 Sales
表的类别。
CALCULATE(SUM(Sales[Amount]), TREATAS(...))
CALCULATE
函数在指定的上下文中计算表达式。在这里,它计算 Sales[Amount]
的总和,同时应用了 TREATAS
函数创建的上下文,从而基于产品类别对销售数据进行聚合。