DAX分享20: 对于航行时间(Operational days)的计算

浏览: 1222

最近工作有点忙。过年最后一天都在奋战。真真是一天酱油都没打。有强迫症,天天关一堆Devops上的case也挺有成就感的。6个字原则。

今年也要学习新东西,感觉我这样的人想学什么应该都很快的吧。

海贼王里,各种各样的海贼团。每个海贼团都有自己的船。其中路飞从最开始的小木桶,后来的黄金梅利号,到现在的万里阳光号。不同的船大概航行了多久呢?在不同日期选择下,船只的航行时间如何呢?各种气体排放量,燃料利用率怎么样呢?先搞个航行时间这个简单的来试一下吧。

需求:

1. 展示需求:对于Power BI需要展示的报表来说,要有一个关于Date时间的切片器Slicer,可以选择不同的年份Year,月份Year Month和日期Date。对于不用的船Vessel Name,也可以做切片来考察不同的船的航行时间。所以也要有一个船Vessel Name的切片器slicer。页面展示的Visualization就简单的有一个Card来展示下总的航行时间Operational Days就可以了。

2. 数据需求:

如果默认没有选择任何的日期,则按照当天来计算当月的航行时间;如果选择了,则按照选择计算的时间来计算航行时间;

如果航行开始时间operation_start_date,小于选择了的时间,则按照选择时间开始计算;如果航行开始时间operation_end_date为空或者大于选择了的时间,则用选择了的时间算作航行结束时间。

时间计算基于每一条船来计算。

数据准备:

  1.  一张Dim_Date的时间维度表,包括年,年月,日字段;

  2.  一张Dim_Vessel的包括各种船的维度信息表,至少包括船的ID,名字已经航行开始和航行结束时间;

  3.  一张Fact事实表,里面包含了时间,燃料消耗情况,各种气体排放情况等等的事实信息表。在本例子里,这个Fact表是一个工具表,只是为了连结Dim_Date和Dim_Vessel来存在,所以只包括几个简单的字段,FK_Vessel,FK_Date,PK_Fact。


建立模型:本例中就三张表。PK和FK之间互相链接。单独建立了一张Measures -Table来放所有的度量信息。

分析:数据方面,对于逻辑需求清楚的,哪怕需求很多很复杂,只要用户提的出来,基本都可以做,除非...

对于这个计算字段,主要有两个基本点。

1, 要获取筛选信息,根据选择的时间和航行时间来比较;

2, 计算的粒度在row level

本来粒度在row level用Calculated Column挺好的。但是Calculated Column不能对Slicer正确接收。所以就只用万能的Measures了。

创建operational days度量


operational days = 
var MaxDate = IF(ISFILTERED(Dim_Date[Date]) || ISFILTERED(Dim_Date[Year Month]) || ISFILTERED(Dim_Date[Year]),MAX(Dim_Date[Date]) ,TODAY())
var MinDate = IF(ISFILTERED(Dim_Date[Date]) || ISFILTERED(Dim_Date[Year Month]) || ISFILTERED(Dim_Date[Year]), MIN(Dim_Date[Date]), DATE(YEAR(TODAY()),1,1))
VAr tt = SUMX(SUMMARIZE(Dim_Vessel,Dim_Vessel[pk_vessel_details],Dim_Vessel[operation_end_date],Dim_Vessel[operation_start_date],"nn",
VAr n1_end = MAX(Dim_Vessel[operation_end_date])
VAr n1_st = MIN(Dim_Vessel[operation_start_date])
VAR nw_st = IF(n1_st < MinDate,MinDate, IF(AND(n1_st>=MinDate,n1_st<= MaxDate),n1_st,BLANK()))
var nw_end = IF(ISBLANK(n1_end),MaxDate,IF(n1_end >=MaxDate,MaxDate,IF(AND(n1_end>MinDate,n1_end<MaxDate),n1_end,MinDate)))
VAr diff = DATEDIFF(nw_st,nw_end,DAY)
return diff),[nn])
return tt


创建报表如下图所示

当没有选择任何Date Filter的时候,校验数据可以看到,Operation_start_date是2017年5月23,Operation_end_date是空,根据逻辑计算Operation_start_date用的是2021年1月1日,operation_end_date用的是2021年3月18日(今天),结果正确。

如果选择了2021年的1,2,3月。结果是89天。

选择了整个2020年检查了一下,目测目前的逻辑都是对的。

好像也挺简单的。其实也也是可以有改进的地方。比如,当operation_end_date如果是空的话,返回今天​

var nw_end = IF(ISBLANK(n1_end),Today(),IF(n1_end >=MaxDate,MaxDate,IF(AND(n1_end>MinDate,n1_end<MaxDate),n1_end,MinDate)))

具体问题具体分析吧。不过基本方法就是在函数里面嵌套变量。


谢谢关注!又是一起加油的一天吖

05m.jpg

推荐 0
本文由 懒胖子 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册