上篇文章介绍了数据模型的相关知识,故本篇文章将介绍两个需要使用表间关系的查找函数,以巩固我们对数据模型相关知识的理解。此外,本文还将介绍一个不需使用关系的查找函数,让我们在跨表查找时具有更多的手段与方法。同时,为了加深对这几个函数的理解,本文还将给出这几个函数的等价写法。本文所介绍的某些内容对初学者来说可能会比较难以理解,如果你是初学者,那么你可以先跳过相关的内容,后续再补上即可。


  在开始介绍之前,我们先来看一下要使用到的数据以及数据模型,具体如下图所示:


  下面介绍第一个关系函数的使用:

  • RELATED
    • 函数作用:从下级表获取上级表的数据
    • 语法结构:RELATED( 'TableName'[ColumnName] )
    • 返回值:根据表间关系所查找到的参数指定列的对应值,结果返回一个标量值

  RELATED必须要在存在基础表的行上下文时才能使用,故该函数一般都是应用于计算列当中,能自动通过表间关系去获取正在添加计算列的那个表的所有上级表的任意列的值。当然该函数并不是只能使用在计算列当中,只要是存在基础表的行上下文时都能使用该函数。

  下面来看一个帮助理解的小例子:现在想从销售表中添加两个列来计算销售金额与销售成本,但销售表中只有每个产品的销量,故我们需要先在产品表中查找到对应产品的成本价格与零售价格。而根据数据模型我们可以知道:销售表是产品表的下级表,产品表则是销售表的上级表,那么我们就可以在销售表中使用RELATED函数来获取其上级表(产品表)中对应产品的成本价格与零售价格,然后再去计算销售金额与销售成本。使用到的计算列公式与结果如下所示:

零售价格-RELATED = RELATED('产品表'[零售价格])

成本价格-RELATED = RELATED('产品表'[成本价格])

销售金额 = '销售表'[销量]*'销售表'[零售价格-RELATED]

销售成本 = '销售表'[销量]*'销售表'[成本价格-RELATED]

  通过上面这个小例子,我们应该就能够掌握RELATED函数的使用,这个函数使用起来很简单,只需要把要获取的数据所在的列填入到参数中即可自动根据表间关系返回对应的值。虽然使用起来比较简单,但要想不出错则必须要对上级表与下级表的概念有一定的理解,而且必须要在存在基础表的行上下文时才能使用。

  “ RELATED函数让我们能够在下级表中通过表间关系去获取上级表的对应数据 ”,这样的说法其实不够准确,当然也没有错就是了。更准确的说法应该是:“ RELATED函数允许我们访问并获取当前表的扩展表上的任意列的值 ”,该说法更严谨与准确,但对没有掌握扩展表原理的人来说则不太容易理解,因此许多的学习资料大都采用前面那种描述。但为了更好地理解RELATED函数的等价写法,我们也必须要了解一下第二种说法。那下面就给出REALTED函数的等价写法,该等价写法利用了基于扩展表原理的逆向筛选,使用到的计算列公式与结果如下所示:

零售价格-RELATED等价写法1 = CALCULATE(VALUES('产品表'[零售价格]))

零售价格-RELATED等价写法2 = LASTNONBLANK('产品表'[零售价格],1)

  RELATED函数的等价写法并不唯一,我们可以写出很多不同的等价写法,但它们都是利用了基于扩展表原理的逆向筛选这一点,可以说是换汤不换药。而且这些等价写法都需要利用到行上下文转换这一特性,因此与RELATED函数相比,等价写法的性能并不高效,所以在有相应的查找需求时直接使用RELATED函数是最佳实践。


  下面介绍第二个关系函数的使用:

  • RELATEDTABLE
    • 函数作用:从上级表获取下级表的数据
    • 语法结构:RELATEDTABLE( 'TableName' )
    • 返回值:根据表间关系所查找到的下级表相应数据,结果返回一个表

  RELATEDTABLE函数的使用条件与RELATED函数基本一致,要在存在基础表的行上下文时才能使用,它会自动根据表间关系去获取下级表的相应数据,然后返回一个表。因为上级表处于关系的一端,下级表处于关系的多端,所以从下级表获取上级表的数据时必然能获取到一个标量值,而反过来的话,上级表的一行数据将对应下级表的多行数据,因此只能返回一个表。而在计算列中,每一个值都必须为标量值,因此若在计算列中使用RELATEDTABLE函数,则必须对其返回的表进行进一步的处理,例如:聚合成一个标量值。

  下面我们来看一个帮助理解的小例子:现在想在产品表中添加一列来计算每个产品的订单数量,但产品表中并没有记录每个产品的订单信息,因此我们必须先在销售表中找到对应产品的记录,然后再统计数量。其中,查找相应的订单记录可以通过RELATEDTABLE函数来完成,而计数则可以使用COUNTROWS函数来统计返回的表的行数。具体的计算列公式与结果如下所示:

订单数量 = COUNTROWS(RELATEDTABLE('销售表'))

  其实RELATEDTABLE函数可以当作是CALCULATETABLE函数的严重阉割版或者说是别名吧,因此把RELATEDTABLE改成CALCULATETABLE,就可以得到RELATEDTABLE函数的等价写法了,等到后续学习了CALCULATE与CALCULATETABLE函数后,RELATEDTABLE就可以忘掉了,这里就简单介绍一下。其等价写法的具体计算列公式与结果如下所示:

订单数量-RELATEDTABLE等价写法 = COUNTROWS(CALCULATETABLE('销售表'))


  下面介绍最后一个函数(该函数也是查找函数,但它并不依赖表间关系,因此在某些情况下能够发挥出巨大作用):

  • LOOKUPVALUE
    • 函数作用:返回满足一个或多个搜索条件所指定的所有条件的行的值
    • 语法结构:LOOKUPVALUE ( <结果列>, <查找列>, <查找值>, [<查找列>, <查找值> … ], [<备选结果>] )
    • 返回值:返回查找到的匹配值,若没有符合的匹配结果,将默认返回空值或指定的备选结果。若搜索到多个匹配值,且所有匹配值均相同,则返回该匹配值,否则默认返回空值或指定的备选结果

  LOOKUPVALUE函数不需要依赖表间关系,因此它的使用也非常简单。事实上,LOOKUPVALUE函数与Excel中的LookUp函数非常相似,而且其参数的顺序刚好是LookUp函数的倒序,这两个函数的区别就是LOOKUPVALUE函数支持多个查找条件罢了,其它都是基本一致。

  下面我们通过一个小例子来学习LOOKUPVALUE函数的使用:获取A产品的零售价格,若不存在匹配值则显示 “ 找不到对应值 ”,这次我们通过度量值来实现,具体的度量值公式与结果如下:

A产品的零售价格-LOOKUPVALUE = LOOKUPVALUE('产品表'[零售价格],'产品表'[产品],"A","找不到对应值")

  为了加深对LOOKUPVALUE函数的理解,下面给出它的等价写法,具体的度量值公式与结果如下:

A产品的零售价格-LOOKUPVALUE-等价写法 = CALCULATE(SELECTEDVALUE('产品表'[零售价格],"找不到对应值"),'产品表'[产品] = "A",ALL())


  本文介绍了三个查找函数,其中有两个关系函数以及一个非关系函数,有了这三个函数后,应付一些基础性的查找匹配需求应该就能做到游刃有余了。虽然本文介绍了这几个函数的各种细节,但想要彻底掌握的话仍然需要自行去练习实践一番。此外,初学者可以暂时跳过等价写法部分,等后续掌握了相应的前置知识后自然就能理解了。


  DAX系列文章中涉及到的案例文件,均已上传到QQ群:344353627,若有需要,可自行加群获取。

  加入Q群