PowerBI开发 第十四篇:DAX 表达式(时间+过滤+关系)

DAX表达式中包含时间关系(Time Intelligence)相关的函数,用于对日期维度进行累加、同比和环比等分析。PowerBI能够创建关系,通过过滤器来对影响计算的上下文。

一,时间关系

DAX表达式有两种方式计算累加和,TOTALxTD()是DATESxTD()的语法糖,使得PowerBI对累加和的计算更加简单。

所有的时间关系函数都包含一个特殊的dates参数,该参数有三种形式:

  • 对date/time列的引用,格式是DateTable[Date_Column]
  • 表格表达式,返回日期/时间类型的单列表
  • 布尔表达式,用于定义日期/时间值的单列表。

为了应用时间关系,按照时间对数据分析,最好单独创建一个日期维度表,并和事实表创建 1 : N  的关联,确保关系是活跃的。日期维度的粒度设置为Day,确保日期维度表包括所有的日期数据。

1,直接计算累加和

DAX中有三个函数直接用于计算累加和,TOTALMTD是按当前月计算累加和、TOTALQTD是按当前季度计算累加和、TOTALYTD是按当前年份计算累加和:

TOTALMTD(<expression>,<dates>[,<filter>]) 
TOTALQTD(<expression>,<dates>[,<filter>])  
TOTALYTD(<expression>,<dates>[,<filter>][,<year_end_date>])  

参数 expression是聚合标量值的表达式,dates是包含日期的字段,filter是过滤器,返回的是布尔值。

例如,计算当前的销售额:

= TOTALMTD(SUM(InternetSales[SalesAmount]),DateTime[DateKey])  

2,返回xTD得所有日期

返回到当前的所有日期,参数dates是只包含一个日期列的表格,函数从dates中取第一个日期作为基准:

DATESMTD(<dates>)  
DATESQTD(<dates>)  
DATESYTD(<dates> [,<year_end_date>]) 

DATESMTD()函数适用于日期维度,该日期维度必须具有连续的非重复日期,从指定数据的第一年的1月1日到去年12月31日,该函数返回一个单列表,该表由上下文中当前日期的月份的第一个月与上下文中的当前日期之间的日期组成。

=CALCULATE(SUM(InternetSales[SalesAmount]), DATESMTD(DateTime[DateKey]))  

3,计算同比(前一个年份的同期)

函数PARALLELPERIOD用于计算平行时期,平行日期是指在参数dates上向前或向后移动多个时间间隔(intervals),该函数返回一个包含平行日期的表,使用该函数可以用于计算同比:

PARALLELPERIOD(<dates>,<number_of_intervals>,<interval>)

参数注释:

  • dates 指定当前的日期
  • interval 指定时间间隔,有效值是 year、quarter和month
  • number_of_intervals 指定向前或向后移动的时间间隔

此函数获取由dates指定的列中的当前日期集,将第一个日期和最后一个日期移动指定的间隔数,然后返回两个移位日期之间的所有连续日期。 如果间隔是月,季度或年的部分范围,则结果中的任何部分月份也将填写以完成整个间隔。

例如,向前回滚12个月,把DateTime[DateKey]中的最小日期和最大日期移动指定的间隔数,然后返回两个移位日期之间的所有连续日期,计算这些日期对应的销量(Sales_Amount)。

CALCULATE([Sales_Amount]*1.1,PARALLELPERIOD(DateTime[DateKey],-12,MONTH))

在该示例中,CALCULATE的第二个参数是一个表格。

另一个函数是SAMEPERIODLASTYEAR(),它是PARALLELPERIOD(DateTime[DateKey],-12,MONTH) 的包装器:

SAMEPERIODLASTYEAR(<dates>)

4,计算环比(前一天/月/季/年)

函数 PREVIOUS+(DAY/MONTH/QUARTER/YEAR),是把指定的日期向前移动的函数,参数是一个包含日期的数据表,返回的是一个包含日期的数据表。

PREVIOUSDAY(<dates>)  
PREVIOUSMONTH(<dates>) 
PREVIOUSQUARTER(<dates>)
PREVIOUSYEAR(<dates>[,<year_end_date>])  

对于PREVIOUSMONTH()函数,该函数使用dates(输入参数)中的第一个日期作为基准,返回该日期上个月的所有日期。 例如,如果dates参数中的第一个日期指的是2009年6月10日,则此函数将返回2009年5月的所有日期。

=CALCULATE(SUM(InternetSales[SalesAmount]), PREVIOUSMONTH(Date[DateKey]))  

二,过滤相关

过滤相关的函数,这些函数跟PowerBI上过滤器图表(Slicer)。

1,过滤器选中的值(唯一值)

过滤器当前选中的值,可以通过函数来获取:

SELECTEDVALUE(<columnName>[, <alternateResult>]) 

参数注释:

  • columnName :是已存的一个列名,不能是表达式,当columnName的上下文仅被过滤为一个不同的值时,该函数返回该值;
  • alternateResult:可选项,默认值是BLANK();如果columnName的上下文被过滤到0个或多个唯一值时,返回alternateResult;

 当过滤器只被选中一个值时,该函数会返回选中的值。

2,过滤器选中的值(多值)

函数VALUES()返回一个单列的表,该列由参数ColumnName指定,该表包含该列的所有唯一值。

VALUES(<ColumnName>)  

该函数受到过滤器的影响,在已过滤的上下文中使用VALUES函数时,VALUES返回的唯一值会受到过滤器的影响。 例如,如果按Region过滤,并返回City的列表,则VALUES()函数仅包括过滤器允许的区域中的那些城市。

=COUNTROWS(VALUES(InternetSales[SalesOrderNumber]))  

Values函数和Distinct函数很相似,唯一不同的是Values函数会返回Unknown,这是因为关联的Table中包含不匹配的数据行,和Left Join的右表中包含NULL值很相似。

结合CONCATENATEX函数,能够把所有过滤器的唯一值连接成字符串。注意,DAX表达式使用 & 进行字符串的连接。

三,关系

表与表之间,可以创建多个关系,但是,只有一个关系是活跃的,该关系是默认的关系。默认情况下,度量表达式都会使用默认的关系应用过滤器,进行交互计算。

USERELATIONSHIP(<columnName1>,<columnName2>) 

USERELATIONSHIP使用模型中的现有关系,通过其端点列来标识关系,该函数用于指定要在特定计算中使用的关系。在USERELATIONSHIP中,关系的状态并不重要,也就是说,关系是否处于活动状态不会影响该功能的使用。 即使关系处于非活动状态,它也将被使用并覆盖模型中可能存在但在函数参数中未提及的任何其他活动关系。

USERELATIONSHIP 函数不返回任何值,仅在计算期间启用指定的关系,并且仅用于把filter作为参数的函数中,例如,CALCULATE、CALCULATETABLE、CLOSINGBALANCEMONTH、CLOSINGBALANCEQUARTER、CLOSINGBALANCEYEAR、TOTALMTD, TOTALQTD 和 TOTALYTD。

 

参考文档:

DAX Reference

DAX Time Intelligence Functions