NATURALINNERJOIN 函数在两个表之间执行内连接(inner join)。你可以使用没有建立关系的表作为参数,函数使用两个表之间的公共列,并且列的数据类型也必须相同,在这种情况下,两个表之间应该至少有一列具有相同的名称和类型。NATURALINNERJOIN 的语法非常简单,用两个表表达式作为参数:
NATURALINNERJOIN- NATURALINNERJOIN ( <LeftTable>, <RightTable> )
复制代码参数 | 属性 | 描述 | LeftTable | | 连接使用的左表表达式. | RightTable | | 连接使用的右表表达式 |
返回的表包括左表中的公共列和两个表的其余列,其中包含两表公共列中的所有相同行(INNER JOIN)
用于无关系表的注意事项:
NATURALINNERJOIN 通常用于无关系的两个表,在这种情况下函数遵循以下规则:
- 结果不保证排序顺序。
- 两表用于连接的公共列必须使用相同的名称,且具有相同的数据类型。
- 连接使用的列必须具有相同的数据沿袭,或者都不具备数据沿袭。
- 连接使用严格的比较语义。不会强制转换类型,例如,1 不等于 1.0。
用于关系表的注意事项:
NATURALINNERJOIN 可以用于存在关系的两个表,在这种情况下,通过 Power BI Desktop 新建表和在 DAX Studio 中创建查询的行为有所不同:
- 在 Power BI Desktop 中使用此函数新建表,两表不能包含同名列,否则将报错。
- 在 DAX Studio 中创建的查询不受同名列的限制,结果可以区分来自不同表的相同列。
示例用法
下面这个示例在查询内部创建连接,目的是演示你可以连接任何表,而不考虑数据模型中是否存在关系,需要注意的是定义关系的列在结果中只出现一次
- EVALUATE
- VAR A =
- UNION (
- ROW ( "Name", "Audio", "Value", 1 ),
- ROW ( "Name", "Audio", "Value", 2 ),
- ROW ( "Name", "Computers", "Value", 3 ),
- ROW ( "Name", "Games", "Value", 4 ),
- ROW ( "Name", "Music", "Value", 5 )
- )
- VAR B =
- UNION (
- ROW ( "Name", "Audio", "Ext", 6 ),
- ROW ( "Name", "Computers", "Ext", 7 ),
- ROW ( "Name", "Computers", "Ext", 8 ),
- ROW ( "Name", "Games", "Ext", 9 ),
- ROW ( "Name", "TV", "Ext", 10 )
- )
- RETURN
- NATURALINNERJOIN ( A, B )
复制代码
查询结果
NATURALINNERJOIN 的连接条件由两个表中具有相同名称和类型的列自动定义。 关系表的 JOIN
当两张表存在关系时,你可以使用 NATURALINNERJOIN 执行类似 SQL 的语法
- SELECT * FROM Sales INNER JOIN Product
- ON Sales.Productkey = Product.Productkey
- ---------- 等价于 -----------
- EVALUATE
- NATURALINNERJOIN ( 'Sales', 'Product' )
复制代码
结果包含 Sales 表的 Productkey 列和两表的其余列。注意,以上操作需要在类似 DAX Studio 的查询工具中完成,你无法在 Power BI Desktop 中使用此查询新建表,因为新表中将包含多个同名的列。
NATURALINNERJOIN 也可以用于没有关系的表,但这种情况下,用于匹配的列不能具有来自不同物理列的数据沿袭。
无关系表的 JOIN
NATURALINNERJOIN 函数基于同名列 JOIN 不存在关系的表,但是这些列不能具有来自不同物理列的数据沿袭,否则可能会在查询模型的物理表时产生混淆。
例如,考虑两个物理表 P_A(ProductKey、Code 和 Color)和 P_B (ProductKey、Name 和 Brand),它们之间没有任何关系。
你不能使用 ProductKey 来 JOIN 这两个表,因为它们虽然名称相同,但具备不同的数据沿袭。如果尝试运行下面的代码:
- EVALUATE
- NATURALINNERJOIN( P_A, P_B )
复制代码
将会得到错误提示:”未检测到公用联接列。联接函数”NATURALINNERJOIN”需要至少一个公用联接列“。在执行 NATURALLEFTOUTERJOIN 时将显示类似的信息。
实现这个连接的关键在于同名列不能具有不同的数据沿袭,为了达到这个目的,你需要改写列表达式阻断数据沿袭:
- EVALUATE
- VAR A =
- SELECTCOLUMNS (
- P_A,
- "ProductKey", P_A[ProductKey]+0,
- "Code", P_A[Code],
- "Color", P_A[Color]
- )
- VAR B =
- SELECTCOLUMNS (
- P_B,
- "ProductKey", P_B[ProductKey]+0,
- "Name", P_B[Name],
- "Brand", P_B[Brand]
- )
- VAR Result =
- NATURALLEFTOUTERJOIN ( A, B )
- RETURN
- Result
复制代码
高亮行在列表达式后面进行加法运算,破坏了原有的数据沿袭。不过从公式性能角度出发,更好的写法是使用 TREATAS:
- EVALUATE
- VAR B_TreatAs =
- TREATAS ( P_A, P_B[ProductKey], P_A[Code], P_A[Color] )
- VAR Result =
- NATURALLEFTOUTERJOIN ( B_TreatAs, P_B )
- RETURN
- Result
复制代码
借助 TREATAS,P_A 表的 ProductKey 列与 P_B 的同名列具备相同的沿袭,可以执行 JOIN |