在我的日期维度中,我有两个层次:
(年-星期-日期)和(年-月-日)
我想在Cube Calculation中检查Date Dimension的当前级别是[Date](最低级别)还是更高的级别。
我怎样才能做到这一点?
后台:我需要这个来计算有多少工作日在一个时期,为一个员工。我目前有这段代码(未经测试),应该为1层次结构做的技巧,但我猜这将失败,当用户使用[年-星期-日期]层次结构。
CASE WHEN
[Date].[Year - Month - Date].CURRENTMEMBER.Level
IS
[Date].[Year - Month - Date].[Date]
THEN
//at day level,
//if there is any duration booked, this is a working day
IIF([Measures].[Duration] = 0,0,1)
ELSE
//at higher than day level,
//count days
COUNT(
// where duration > 0 (employee work day)
FILTER(
Descendants([Date].[Year - Month - Date].CURRENTMEMBER, [Date].[Year - Month - Date].[Date]),
[Measures].[Duration] > 0
)
)
END
tl;dr我如何使上面的代码以最干净的方式也适用于[年-周-日期]层次结构
让我们假设层次结构(即属性)[Date]。[日期]的存在。如果是这种情况,可以简化为:
COUNT(
FILTER( Existing [Date].[Date].members, [Measures].[Duration] > 0 )
)
Existing将强制在[Date]维度上应用一个自动存在。这主要是一个性能改进,因为它避免了评估(事实)所有元组。
一旦前面的例子清楚了,我们可以将它与您的版本合并,以获得最快的解决方案(不需要第一个iif):
COUNT(
FILTER( Existing
Descendants([Date].[Year - Month - Date].CURRENTMEMBER, [Date].[Year - Month - Date].[Date],self)
, [Measures].[Duration] > 0 )
)
进一步的改进可能是添加一个具有不同聚合类型的新度量,或者添加一个iif来更改两个层次结构中的哪一个用于后代(例如当前成员和默认成员不相等的那个)
如果您正在寻找最简洁的方法来计算一个时间段内有多少工作日,您必须模拟常规度量的行为。否则,你会得到错误或坏的数据在多选[日期]的情况下。此外,最好去掉Count(Filter(…))表达式以保持块计算模式(参见优化MDX中的Count(Filter(…))表达式)。要做到这一点,请遵循以下步骤:
- 进入数据源视图
- 在[Duration]列旁边创建一个新的命名计算(在同一事实表中)
- 列名为"Working days",表达式为"null"。
- 根据"工作日"一栏创建一个新的常规度量。聚合函数为Sum。
-
写入MDX脚本:
( [Date].[Date].[Date].Members, [Measures].[Working days] ) = Iif( [Measures].[Duration] > 0, 1, null );
IsLeaf()
将告诉您成员是否处于底层。
查看计算脚本中的SCOPE命令,我为我的YMD日历和YWD日历做了类似的事情:
CREATE MEMBER CurrentCube.Measures.Example AS NULL //Dummy will be calc'd later
SCOPE (DESCENDANTS([Date].[Calender Y M D],,AFTER));
Measures.Example = 1; //Fill in for monthly calcs
END SCOPE
SCOPE (DESCENDANTS([Date].[Calender Y W D],,AFTER));
Measures.Example = 2; //Fill in for weekly calcs
END SCOPE
,,AFTER的语法是排除所有成员,如果我没记错的话,我试图把链接分开,但找不到它。或者,如果使用ALL成员计算效果良好,则只需使用SCOPE([Date].[Calender Y W D])