NATURALLEFTOUTERJOIN 函数的行为类似于 NATURALINNERJOIN,惟一的区别是它为第一参数的表表达式执行左外连接
,语法使用两个返回表的表达式作为参数,它们的顺序很重要:
NATURALLEFTOUTERJOIN
NATURALLEFTOUTERJOIN ( <LeftTable>, <RightTable> )
参数 | 属性 | 描述 |
---|---|---|
LeftTable | 连接使用的左表表达式. | |
RightTable | 连接使用的右表表达式 |
使用左外部连接语义将左表与右表连接起来,结果表包含左表的所有行,右表的匹配行。
用于无关系表的注意事项:
NATURALLEFTOUTERJOIN 通常用于无关系的两个表,在这种情况下函数遵循以下规则:
- 结果不保证排序顺序。
- 两表用于连接的公共列必须使用相同的名称,且具有相同的数据类型。
- 连接使用的列必须具有相同的数据沿袭,或者都不具备数据沿袭。
- 连接使用严格的比较语义。不会强制转换类型,例如,1 不等于 1.0。
用于关系表的注意事项:
NATURALLEFTOUTERJOIN 可以用于存在关系的两个表,在这种情况下,通过 Power BI Desktop 新建表和在 DAX Studio 中创建查询的行为有所不同:
- 在 Power BI Desktop 中使用此函数新建表,两表不能包含同名列,否则将报错。
- 在 DAX Studio 创建的查询不受同名列的限制,结果可以区分来自不同表的相同列。
示例用法
如图所示,这一次,表 A 与表 B 应用左外连接而不是内连接
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 NATURALLEFTOUTERJOIN ( A, B )
在本例中,结果还包括只在第一个表中不存在于第二个表的行(Music 行)
关系表的 JOIN
当两张表存在关系时,你可以使用 NATURALLEFTOUTERJOIN 执行类似 SQL 的语法
SELECT * FROM Sales LEFT OUTER JOIN Product ON Sales.Productkey = Product.Productkey ---------- 等价于 ----------- EVALUATE NATURALLEFTOUTERJOIN ( 'Sales', 'Product' )
结果包含 Sales 表的 Productkey 列和两表的其余列。注意,以上操作需要在类似 DAX Studio 的查询工具中完成,你无法在 Power BI Desktop 中使用此查询新建表,因为新表中将包含多个同名的列。
NATURALLEFTOUTERJOIN 也可以用于没有关系的表,但这种情况下,用于匹配的列不能具有来自不同物理列的数据沿袭。
无关系表的 JOIN
NATURALLEFTOUTERJOIN 函数基于同名列 JOIN 不存在关系的表,但是这些列不能具有来自不同物理列的数据沿袭,否则可能会在查询模型的物理表时产生混淆。
例如,考虑两个物理表 P_A(ProductKey、Code 和 Color)和 P_B (ProductKey、Name 和 Brand),它们之间没有任何关系。
你不能使用 ProductKey 来 JOIN 这两个表,因为它们虽然名称相同,但具备不同的数据沿袭。如果尝试运行下面的代码:
EVALUATE NATURALLEFTOUTERJOIN( P_A, P_B )
将会得到错误提示:”未检测到公用联接列。联接函数”NATURALLEFTOUTERJOIN”需要至少一个公用联接列“。在执行 NATURALINNERJOIN 时将显示类似的信息。
实现这个连接的关键在于同名列不能具有不同的数据沿袭,为了达到这个目的,你需要改写列表达式阻断数据沿袭:
老师您好,这个函数是不是不好实现类似SQL中的条件匹配啊,例如 t1 left join t2 on t1.col1 = t2.col2 and t1.col3 IS NULL的逻辑。
另外在这篇文章的末尾使用Treatas,这样会导致左表去重,有时候去重并不是一开始不是实际想要的效果,而是单纯想在两张多表之间实现Join。这个在DAX中是否有可实现的方案呢,我认为DAX基于微软的xmSQL,是否应该可以实现SQL能实现的所有逻辑。