[知识体系] 理解 NATURALINNERJOIN

  [复制链接]
查看192305 | 回复158 | 2021-2-21 18:51:37 | 显示全部楼层 |阅读模式
NATURALINNERJOIN 函数在两个表之间执行内连接(inner join)。你可以使用没有建立关系的表作为参数,函数使用两个表之间的公共列,并且列的数据类型也必须相同,在这种情况下,两个表之间应该至少有一列具有相同的名称和类型NATURALINNERJOIN 的语法非常简单,用两个表表达式作为参数:

NATURALINNERJOIN
  1. NATURALINNERJOIN ( <LeftTable>, <RightTable> )
复制代码
参数属性描述
LeftTable连接使用的左表表达式.
RightTable连接使用的右表表达式


返回的表包括左表中的公共列和两个表的其余列,其中包含两表公共列中的所有相同行(INNER JOIN)

用于无关系表的注意事项:

NATURALINNERJOIN 通常用于无关系的两个表,在这种情况下函数遵循以下规则:


  • 结果不保证排序顺序。
  • 两表用于连接的公共列必须使用相同的名称,且具有相同的数据类型。
  • 连接使用的列必须具有相同的数据沿袭,或者都不具备数据沿袭
  • 连接使用严格的比较语义。不会强制转换类型,例如,1 不等于 1.0。

用于关系表的注意事项:

NATURALINNERJOIN 可以用于存在关系的两个表,在这种情况下,通过 Power BI Desktop 新建表和在 DAX Studio 中创建查询的行为有所不同:


  • 在 Power BI Desktop 中使用此函数新建表,两表不能包含同名列,否则将报错。
  • 在 DAX Studio 中创建的查询不受同名列的限制,结果可以区分来自不同表的相同列。

示例用法

下面这个示例在查询内部创建连接,目的是演示你可以连接任何表,而不考虑数据模型中是否存在关系,需要注意的是定义关系的列在结果中只出现一次
  1. EVALUATE
  2. VAR A =
  3.     UNION (
  4.         ROW ( "Name", "Audio", "Value", 1 ),
  5.         ROW ( "Name", "Audio", "Value", 2 ),
  6.         ROW ( "Name", "Computers", "Value", 3 ),
  7.         ROW ( "Name", "Games", "Value", 4 ),
  8.         ROW ( "Name", "Music", "Value", 5 )
  9.     )
  10. VAR B =
  11.     UNION (
  12.         ROW ( "Name", "Audio", "Ext", 6 ),
  13.         ROW ( "Name", "Computers", "Ext", 7 ),
  14.         ROW ( "Name", "Computers", "Ext", 8 ),
  15.         ROW ( "Name", "Games", "Ext", 9 ),
  16.         ROW ( "Name", "TV", "Ext", 10 )
  17.     )
  18. RETURN
  19.     NATURALINNERJOIN ( A, B )
复制代码

7067211947461.png

查询结果
NATURALINNERJOIN 的连接条件由两个表中具有相同名称和类型的列自动定义。
关系表的 JOIN

当两张表存在关系时,你可以使用 NATURALINNERJOIN 执行类似 SQL 的语法



7067211947462.png



  1. SELECT * FROM Sales INNER JOIN Product
  2. ON Sales.Productkey = Product.Productkey

  3. ---------- 等价于 -----------

  4. EVALUATE
  5. NATURALINNERJOIN ( 'Sales', 'Product' )
复制代码

结果包含 Sales 表的 Productkey 列和两表的其余列。注意,以上操作需要在类似 DAX Studio 的查询工具中完成,你无法在 Power BI Desktop 中使用此查询新建表,因为新表中将包含多个同名的列。


NATURALINNERJOIN 也可以用于没有关系的表,但这种情况下,用于匹配的列不能具有来自不同物理列的数据沿袭

无关系表的 JOIN

NATURALINNERJOIN 函数基于同名列 JOIN 不存在关系的表,但是这些列不能具有来自不同物理列的数据沿袭,否则可能会在查询模型的物理表时产生混淆。


例如,考虑两个物理表 P_A(ProductKey、Code 和 Color)和 P_B (ProductKey、Name 和 Brand),它们之间没有任何关系。



7067211947463.png



你不能使用 ProductKey 来 JOIN 这两个表,因为它们虽然名称相同,但具备不同的数据沿袭。如果尝试运行下面的代码:
  1. EVALUATE
  2. NATURALINNERJOIN( P_A, P_B )
复制代码

将会得到错误提示:”未检测到公用联接列。联接函数&#8221;NATURALINNERJOIN&#8221;需要至少一个公用联接列“。在执行 NATURALLEFTOUTERJOIN 时将显示类似的信息。


实现这个连接的关键在于同名列不能具有不同的数据沿袭,为了达到这个目的,你需要改写列表达式阻断数据沿袭:
  1. EVALUATE
  2. VAR A =
  3.     SELECTCOLUMNS (
  4.         P_A,
  5.         "ProductKey", P_A[ProductKey]+0,
  6.         "Code", P_A[Code],
  7.         "Color", P_A[Color]
  8.     )
  9. VAR B =
  10.     SELECTCOLUMNS (
  11.         P_B,
  12.         "ProductKey", P_B[ProductKey]+0,
  13.         "Name", P_B[Name],
  14.         "Brand", P_B[Brand]
  15.     )
  16. VAR Result =
  17.     NATURALLEFTOUTERJOIN ( A, B )
  18. RETURN
  19.     Result
复制代码

高亮行在列表达式后面进行加法运算,破坏了原有的数据沿袭。不过从公式性能角度出发,更好的写法是使用 TREATAS
  1. EVALUATE
  2. VAR B_TreatAs =
  3.     TREATAS ( P_A, P_B[ProductKey], P_A[Code], P_A[Color] )
  4. VAR Result =
  5.     NATURALLEFTOUTERJOIN ( B_TreatAs, P_B )
  6. RETURN
  7.     Result
复制代码

借助 TREATAS,P_A 表的 ProductKey 列与 P_B 的同名列具备相同的沿袭,可以执行 JOIN
回复

使用道具 举报

一万 | 2021-4-24 13:02:39 来自手机 | 显示全部楼层
支持你哈...................................
回复

使用道具 举报

tian_junwei | 2021-5-23 09:13:05 | 显示全部楼层
这套视频很不错!!!!
回复

使用道具 举报

aarion | 2021-8-29 22:09:16 来自手机 | 显示全部楼层
非常好,顶一下
回复

使用道具 举报

文文 | 2021-10-2 08:27:29 | 显示全部楼层
啥玩应呀
回复

使用道具 举报

文泰 | 2021-10-11 09:09:24 来自手机 | 显示全部楼层
支持,一直很喜欢老师的课程
回复

使用道具 举报

老何 | 2021-10-27 11:53:41 | 显示全部楼层
前排支持下
回复

使用道具 举报

发动机 | 2021-10-31 23:56:22 来自手机 | 显示全部楼层
好,很好,非常好!
回复

使用道具 举报

jinchang | 2021-12-28 12:50:43 来自手机 | 显示全部楼层
楼下的接上
回复

使用道具 举报

Nicky | 2022-1-27 12:37:22 | 显示全部楼层
元芳你怎么看?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则