白茶曾介绍过OFFSET可以用来解决同环比的问题,其实微软最近推出的开窗函数WINDOW也可以用来解决同环比。
WINDOW函数基础语法
WINDOW ( from[, from_type], to[, to_type][, <relation>][, <orderBy>][, <blanks>][, <partitionBy>][, <matchBy>] )
参数介绍:
from:表示窗口开始的位置,正负数均可,可以是固定值,也可以是DAX表达式。
from_type:修改from行为,有两个选项ABS(绝对位置)和REL(相对位置)。
to:表示窗口结束的位置,正负数均可,可以是固定值,也可以是DAX表达式。
to_type:修改to行为,有两个选项ABS(绝对位置)和REL(相对位置)。
relation:表表达式,后续参数orderby,partitionby,matchby的内部参数,都需要来自它或相关表。
orderby:可选项,排序依据。
blanks:可选项,保留参数,可以忽略。
partitionby:可选项,分区定义,参照SQL的开窗分区即可。
matchby:可选项,定义匹配数据和标识当前行的列的语句。
PS:
from和to的1代表向后移动一行,-1代表向前移动一行,0代表当前位置。
其他参数与OFFSET和INDEX函数一致,这里就不过多介绍了。
接下来我们搭配应用场景来看一下如何使用WINDOW函数。
先来看看本期的案例数据:
案例数据就一张Sales的销售事实表,表结构也相对简单,将其导入到PowerBI中。
添加如下日期表,并建立模型关系。
Date =
GENERATE (
CALENDAR ( MIN ( 'Sales'[DATE] ), MAX ( 'Sales'[DATE] ) ),
VAR DA = [Date]
VAR YEAR =
YEAR ( DA )
VAR QUARTER =
"Q" & FORMAT ( DA, "Q" )
VAR MONTE =
FORMAT ( DA, "MM" )
VAR DAY =
DAY ( DA )
RETURN
ROW (
"Year", YEAR,
"Quarter", QUARTER,
"Month", MONTE,
"DayOfMonth", DAY,
"YearQuarter", YEAR & QUARTER,
"YearMonth", YEAR & MONTE,
"YearMonthCount",
YEAR * 12 + MONTE ----新增列
)
)
模型关系如下:
添加如下基础度量值:
销售数量:
Quantity =
SUM ( Sales[Quantity] )
环比:
Offset环比% =
VAR LastMonth =
CALCULATE ( [Quantity], OFFSET ( -1, ALL ( 'Date'[Year], 'Date'[YearMonth] ) ) )
RETURN
DIVIDE ( [Quantity] - LastMonth, LastMonth )
同比:
Offset同比% =
VAR LastYear =
CALCULATE ( [Quantity], OFFSET ( -12, ALL ( 'Date'[Year], 'Date'[YearMonth] ) ) )
RETURN
DIVIDE ( [Quantity] - LastYear, LastYear )
这是我们之前利用OFFSET函数的写法,结果如下:
有了WINDOW函数,我们还可以这么写:
环比:
Window环比% =
VAR LastYear =
CALCULATE (
[Quantity],
WINDOW ( -1, REL, -1, REL, ALL ( 'Date'[Year], 'Date'[YearMonth] ) )
)
RETURN
DIVIDE ( [Quantity] - LastYear, LastYear )
同比:
Window同比% =
VAR LastYear =
CALCULATE (
[Quantity],
WINDOW ( -12, REL, -12, REL, ALL ( 'Date'[Year], 'Date'[YearMonth] ) )
)
RETURN
DIVIDE ( [Quantity] - LastYear, LastYear )
结果如下:
二者结果是一致的。
从执行性能上来看,OFFSET函数的效果是最优的。
无论是对比之前的时间智能函数的写法,还是对比日期表加列的写法,包括本期对比WINDOW函数的写法,OFFSET在同环比计算上的速度都是最优的。
而WINDOW函数,因为有from和to两个定位值,因此性能上面对比OFFSET是有损耗的。