本篇文章将介绍时间智能函数中的 DATESBETWEEN 函数与 DATESINPERIOD 函数。
注意,在使用时间智能函数时需要创建日期表,虽然目前的时间智能函数已经优化了很多次,许多限制都已经放开,但创建日期表仍然是一个最佳实践,能够避开许多容易出错的地方。
另外,由于时间智能函数的使用依赖于日期表,而日期表又比较特殊,因此在阅读时间智能函数系列的文章前,最好已经阅读并理解这篇前置文章:32、应用日期表时的注意事项 。
DATESBETWEEN 函数
语法:
DATESBETWEEN ( <dates>, <start_date>, <end_date> )
作用:返回一个包含一列日期的表,这些日期从指定的开始日期,一直持续到指定的结束日期。
参数说明:
1、dates,该参数只能是对日期字段的列引用,代表将从哪个日期字段中返回指定的日期范围。
2、start_date,返回日期标量值的表达式,可以为空。
3、end_date,返回日期标量值的表达式,可以为空。
注意事项:
1、如果 start_date 为空,则 start_date 将是第一参数指定的日期列中的最小日期。
2、如果 end_date 为空,则 end_date 将是第一参数指定的日期列中的最大日期。
3、返回的日期包括 start_date 和 end_date。
4、如果 start_date 大于 end_date,则返回空表。
5、返回的日期只包括那些存在于第一参数指定的日期列中的日期。
辅助理解的例子:
1、DATESBETWEEN 函数的使用示例如下:
由于结束日期使用了空值,因此将用第一参数指定的日期列中的最大日期(2017/12/31)代替,所以上面的表达式理论上应该返回2012/1/1 – 2017/12/31。但因为 DATESBETWEEN 函数返回的日期只包括那些存在于第一参数指定的日期列中的日期,所以最终只返回了2016/1/1 – 2017/12/31。
2、如果用代码来表示的话,那么 DATESBETWEEN 函数的等价写法如下:
DATESBETWEEN('日期表'[Date],DATE(2016,1,5),DATE(2017,8,5))
等价于:
VAR start_date = DATE(2016,1,5)
VAR end_date = DATE(2017,8,5)
VAR start_ =
IF(
start_date<>BLANK(),
start_date,
MINX(ALL('日期表'[Date]),'日期表'[Date])
)
VAR end_ =
IF(
end_date<>BLANK(),
end_date,
MAXX(ALL('日期表'[Date]),'日期表'[Date])
)
RETURN
FILTER(ALL('日期表'[Date]),'日期表'[Date]>=start_ && '日期表'[Date]<=end_)
DATESINPERIOD 函数
语法:
DATESINPERIOD ( <dates>, <start_date>, <number_of_intervals>, <interval> )
作用:返回一个包含一列日期的表,这些日期从指定的开始日期起始,然后往过去或未来偏移,持续到指定的日期间隔区间。
参数说明:
1、dates,该参数只能是对日期字段的列引用,代表将从哪个日期字段中返回指定的日期范围。
2、start_date,返回日期标量值的表达式,可以为空。
3、number_of_intervals,偏移的间隔区间数量,负数代表向过去偏移,正数代表向未来偏移。
4、interval,间隔区间类型,为指定的枚举值:YEAR、QUARTER、MONTH、DAY,非字符串,不需要使用双引号包括。
注意事项:
1、如果 start_date 为空,则 start_date 将是第一参数指定的日期列中的最小日期。
2、如果number_of_intervals为空值或零,则返回结果为空。
3、返回的日期范围为半开半闭区间,包含偏移起始的start_date,但不包含偏移结束时的那个日期。
4、返回的日期只包括那些存在于第一参数指定的日期列中的日期。
辅助理解的例子:
1、下面是 DATESINPERIOD 函数的一些示例表达式与结果:
DATESINPERIOD('date'[Date],DATE(2018,2,1),10,DAY) // 返回 2018年2月1日 至 2018年2月10日,不含2018年2月11日
DATESINPERIOD('date'[Date],DATE(2018,2,1),1,MONTH) // 返回 2018年2月1日 至 2018年2月28日,不含2018年3月1日
DATESINPERIOD('date'[Date],DATE(2018,2,1),-1,MONTH) // 返回 2018年1月2日 至 2018年2月1日,不含2018年1月1日
DATESINPERIOD('date'[Date],DATE(2018,2,1),1,QUARTER) // 返回 2018年2月1日 至 2018年4月30日,不含2018年5月1日
DATESINPERIOD('date'[Date],DATE(2018,2,1),1,YEAR) // 返回 2018年2月1日 至 2019年1月31日,不含2019年2月1日
需要重点注意的是,因为偏移是从第二参数的 start_date 开始数起的,所以 DATESINPERIOD 函数返回的日期范围为半开半闭区间,包含偏移起始的 start_date,但不包含偏移结束时的那个日期。
该函数的行为其实很简单,可以先将第二参数的开始日期加减N个指定的日期间隔区间,得到偏移结束后的日期,然后就可以确定最终返回的日期范围了。
2、下面是借助 DATESINPERIOD 函数来计算最近N天的案例:
其中,切片器的字段来自周期计算表,主要用于定义每个周期包含多少天,该计算表的表达式为:
周期 =
SELECTCOLUMNS(
{(0,"昨天",1),(1,"最近一周",7),(2,"最近一月",30),(3,"最近三月",90)},
"索引",[Value1],
"周期",[Value2],
"天数",[Value3]
)
3、DATESINPERIOD 函数还有一个很常用的场景,那就是用来计算本周至今(WTD)的数据,如下图所示:
由于没有计算本周至今(WTD)的专用函数,所以 DATESINPERIOD 函数的这个套路是必须要掌握的。
总结
本篇文章介绍了时间智能函数中的 DATESBETWEEN 函数与 DATESINPERIOD 函数,这两个函数能够直接返回所需要的日期区间,也是很常用到的时间智能函数,建议掌握,特别是 DATESINPERIOD 函数。