alt

白茶曾介绍过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函数。

alt

先来看看本期的案例数据:

alt

案例数据就一张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   ----新增列
        )
)

模型关系如下:

alt

添加如下基础度量值:

销售数量:

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函数的写法,结果如下:

alt

有了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 )

结果如下:

alt

二者结果是一致的。

alt

从执行性能上来看,OFFSET函数的效果是最优的。

无论是对比之前的时间智能函数的写法,还是对比日期表加列的写法,包括本期对比WINDOW函数的写法,OFFSET在同环比计算上的速度都是最优的。

而WINDOW函数,因为有from和to两个定位值,因此性能上面对比OFFSET是有损耗的。

alt alt