[知识体系] 理解 NATURALLEFTOUTERJOIN

  [复制链接]
查看110485 | 回复120 | 2021-2-21 18:51:28 | 显示全部楼层 |阅读模式
NATURALLEFTOUTERJOIN 函数的行为类似于 NATURALINNERJOIN,惟一的区别是它为第一参数的表表达式执行左外连接,语法使用两个返回表的表达式作为参数,它们的顺序很重要:

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


使用左外部连接语义将左表与右表连接起来,结果表包含左表的所有行,右表的匹配行。

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

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


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

用于关系表的注意事项:

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


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

示例用法

如图所示,这一次,表 A 与表 B 应用左外连接而不是内连接
  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.     NATURALLEFTOUTERJOIN ( A, B )
复制代码

在本例中,结果还包括只在第一个表中不存在于第二个表的行(Music 行)


7066211942021.png

查询结果

关系表的 JOIN

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



7066211942022.png



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

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

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

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


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

无关系表的 JOIN

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


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



7066211942023.png



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

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


实现这个连接的关键在于同名列不能具有不同的数据沿袭,为了达到这个目的,你需要改写列表达式阻断数据沿袭:
  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:00:49 | 显示全部楼层
站位支持
回复

使用道具 举报

MGM | 2021-7-6 09:11:23 来自手机 | 显示全部楼层
前排顶,很好!
回复

使用道具 举报

kevin | 2021-7-15 20:21:02 来自手机 | 显示全部楼层
我是个凑数的。。。
回复

使用道具 举报

爱情密码 | 2021-8-31 22:54:41 | 显示全部楼层
支持楼主,用户楼主,楼主英明呀!!!
回复

使用道具 举报

笑眯眯 | 2021-9-3 15:52:32 | 显示全部楼层
老大,这个说的很好,这个真不错!
回复

使用道具 举报

亨少 | 2021-9-16 19:20:31 来自手机 | 显示全部楼层
看起来不错
回复

使用道具 举报

tiantian | 2021-10-17 21:35:57 | 显示全部楼层
楼主呀,,,您太有才了。。。
回复

使用道具 举报

zhanghaiming | 2021-11-10 23:51:58 | 显示全部楼层
谢谢,一直在学习云发教育课程!
回复

使用道具 举报

zhu8zhu | 2021-11-13 11:31:07 | 显示全部楼层
忙完了,来看看视频
回复

使用道具 举报

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

本版积分规则