【问题标题】:Check if level in any dimension hierarchy is [Foo]检查任何维度层次结构中的级别是否为 [Foo]
【发布时间】:2011-07-05 08:21:04
【问题描述】:

在我的日期维度中,我有 2 个层次结构:

[年 - 周 - 日期][年 - 月 - 日期]

如果日期维度的当前级别是 [Date](最低级别)或更高级别,我想检查 Cube Calculation。

我怎样才能做到这一点?

背景:我需要这个来计算员工在一段时间内有多少工作日。 我目前有这段代码(未经测试)应该可以解决 1 个层次结构的问题,但我想当用户使用 [Year - Week - Date] 层次结构时这会失败。

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如何让上述代码以最简洁的方式也适用于 [Year - Week - Date] 层次结构。

【问题讨论】:

  • 我刚刚发现了 Descendants 函数中的 'SELF' 标志,这避免了我的问题,但我仍然很好奇

标签: ssas mdx cube dimension


【解决方案1】:

让我们假设层次结构(又名属性)[Date].[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 以更改两个层次结构中的哪一个用于后代(例如 currentmember 和 defaulmember 不相等的那个)

【讨论】:

    【解决方案2】:

    如果您正在寻找最简洁的方法来计算一段时间内有多少个工作日,您必须模仿常规测量的行为。否则,如果在 [日期] 上进行多选,您将收到错误或错误数据。此外,最好去掉 Count(Filter(...)) 表达式以保持块计算模式(参见Optimizing Count(Filter(...)) expressions in MDX)。为此,请按以下步骤操作:

    1. 转到数据源视图。
    2. 在 [Duration] 列旁边(在同一个事实表中)创建一个新的命名计算。
    3. 列名称为“工作日”,表达式为“null”。
    4. 基于“工作日”列创建新的常规度量。聚合函数为 Sum。
    5. 在 MDX 脚本中编写:

      (
          [Date].[Date].[Date].Members,
          [Measures].[Working days]
      ) = Iif( [Measures].[Duration] > 0, 1, null );
      

    【讨论】:

    • 很有趣,会研究这个。
    【解决方案3】:

    IsLeaf() 会告诉你成员是否处于底层。

    【讨论】:

      【解决方案4】:

      查看计算脚本中的 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 成员,我正在尝试区分链接但找不到它。或者,如果计算适用于 ALL 成员,只需使用 SCOPE([Date].[Calender Y W D])

      【讨论】:

      • 这个解决方案有什么优势?不能为级别而不是成员定义范围(这可能很大)..(只是好奇)
      • @icCube 作用域对任何子立方体都有效,这只是为了展示如何按层次结构改变计算,因为 MDX 似乎没有检测当前正在运行的层次结构的好方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 1970-01-01
      相关资源
      最近更新 更多