使用Mondrian/MDX按季度分组:总和和计数与平均值的行为

使用Mondrian/MDX按季度分组:总和和计数与平均值的行为,mdx,pentaho,olap,mondrian,Mdx,Pentaho,Olap,Mondrian,我试图对季度分组进行汇总(求和和和平均值),但根据我使用的方法,我会得到不同的结果。我想知道为什么 以下基本查询说明了我的数据(Pentaho SteelWheels示例): 结果是: Time | Sales |Quantity -----+------------+--------- QTR1 | 445094.69 | 4561 QTR1 | 877418.97 | 8694 QTR1 | 1111260.1 | 10995 QTR2 | 564842.02 | 5

我试图对季度分组进行汇总(求和和和平均值),但根据我使用的方法,我会得到不同的结果。我想知道为什么

以下基本查询说明了我的数据(Pentaho SteelWheels示例):

结果是:

Time |  Sales     |Quantity
-----+------------+---------
QTR1 |  445094.69 |  4561
QTR1 |  877418.97 |  8694
QTR1 | 1111260.1  | 10995
QTR2 |  564842.02 |  5695
QTR2 |  847713.97 |  8443
QTR2 |  869565.24 |  8480
QTR3 |  687268.87 |  6629
QTR3 | 1145308.08 | 11311
QTR4 | 1980178.42 | 19554
QTR4 | 2117298.82 | 20969
因此,行标题是季度的标题,QTR1、QTR2、QTR3和QTR4的不同出现都属于特定年份(因此第一个QTR1实际上是[2003].[QTR1],第二个是[2004].[QTR1],第三个是[2005].[QTR1],依此类推)

我想要的是一个结果,它将[QTR1]的所有出现视为一个单独的组,其中单元格值聚合销售数量度量。假设我希望至少看到总和(所有季度1、2、3和4的总数量,不考虑年份)和平均值(所有季度1、2、3和4的平均数量,不考虑年份)

现在,我看到了这个问题:

虽然这个解决方案确实有帮助,但它要求我列举我需要分组的季度。我想动态地这样做

我提出了这个问题:

WITH
SET     OrderedQuarters
AS      Order(
          Time.Quarters.Members,
          Time.CurrentMember.Caption,
          BASC
        )
SET     UniqueQuarters
AS      Filter(
          OrderedQuarters,
          OrderedQuarters.Item(
            OrderedQuarters.CurrentOrdinal-1
          ).Caption <> Time.CurrentMember.Caption
        )
MEMBER  Measures.QuantitySum
AS      Sum(
          Filter(
            OrderedQuarters,
            UniqueQuarters.Item(
              UniqueQuarters.CurrentOrdinal
            ).Caption = Time.CurrentMember.Caption
          )
        , Measures.Quantity
        )
MEMBER  Measures.Counter
AS      Count(
          Filter(
            OrderedQuarters,
            UniqueQuarters.Item(
              UniqueQuarters.CurrentOrdinal
            ).Caption = Time.CurrentMember.Caption
          )
        )
MEMBER  Measures.[Sum over Count]
AS      Measures.QuantitySum / Measures.Counter
MEMBER  Measures.AvgQuantity
AS      Avg(
          Filter(
            OrderedQuarters,
            UniqueQuarters.Item(
              UniqueQuarters.CurrentOrdinal
            ).Caption = Time.CurrentMember.Caption
          )
        , Measures.Quantity
        )
SELECT {Measures.QuantitySum
       ,Measures.Counter
       ,Measures.[Sum over Count]
       ,Measures.AvgQuantity} ON COLUMNS
,       UniqueQuarters        ON ROWS
FROM    SteelWheelsSales
现在,虽然[QuantitySum]和[Sum over Count]度量给了我想要的结果,但我并不完全满意:

  • [QuantitySum]使用Sum显式计算。我希望隐式计算它,因为它已经在多维数据集中定义为一个总和聚合度量
  • 我明确地计算了[Sum over Count]计算度量中的平均值。我想使用Avg()并尝试使用Measures.AvgQuantity,但这似乎与我期望的方式不符。它似乎计算了第一季度的平均值,然后又重复了其他季度的平均值。为什么?Sum和Count似乎完全按照预期工作,为什么Avg如此不同
    就Microsofts AdvWrks多维数据集而言,日期维度的结构稍有不同,以便在Qrt1/Qtr2之间进行聚合。。这是很容易实现的

    以下是包含的层次结构的整体集合:

    以下是与宿舍相连的两个层次结构:

    Date.Calendar用户层次结构的级别包括成员标题中的年份:

    而属性层次结构
    Date.Calendar Quarter of Year
    的标题与脚本中的标题类似:

    WITH 
      SET OrderedQuarters AS 
        Order
        (
          [Date].[Calendar Quarter of Year].[Calendar Quarter of Year].MEMBERS
         ,[Date].[Calendar Quarter of Year].CurrentMember.Member_Caption
         ,BASC
        ) 
      MEMBER Measures.AvgOrderCount AS 
        Avg
        (
          (EXISTING 
            [Date].[Calendar Year].[Calendar Year].MEMBERS)
         ,[Measures].[Order Count]
        ) 
    SELECT 
      {
        [Measures].[Order Count]
       ,[Measures].[AvgOrderCount]
      } ON COLUMNS
     ,OrderedQuarters ON ROWS
    FROM [Adventure Works];
    

    它返回以下内容:

    现有功能的替代方法是与季度层次结构的当前成员交叉连接。这会产生相同的结果:

    WITH 
      SET OrderedQuarters AS 
        Order
        (
          [Date].[Calendar Quarter of Year].[Calendar Quarter of Year].MEMBERS
         ,[Date].[Calendar Quarter of Year].CurrentMember.Member_Caption
         ,BASC
        ) 
      MEMBER Measures.AvgOrderCount AS 
        Avg
        (
          ([Date].[Calendar Quarter of Year].CurrentMember*  //EXISTING 
            [Date].[Calendar Year].[Calendar Year].MEMBERS)
         ,[Measures].[Order Count]
        ) 
    SELECT 
      {
        [Measures].[Order Count]
       ,[Measures].[AvgOrderCount]
      } ON COLUMNS
     ,OrderedQuarters ON ROWS
    FROM [Adventure Works];
    
    因此,参考埃森的答案,如果蒙德里安没有现有的,那么这可能会迫使计算上下文:

    MEMBER  Measures.AvgQuantity
    AS      Avg(
              (Time.Years.Members * Time.CurrentMember)
            , Measures.Quantity
            )
    
    基于以上内容,我想知道您是否将过滤集与年份交叉连接:

    MEMBER  Measures.AvgQuantity
    AS      Avg(
              Filter(
                OrderedQuarters,
                UniqueQuarters.Item(
                  UniqueQuarters.CurrentOrdinal
                ).Caption = Time.CurrentMember.Caption
              )
             * Time.Years.Members
            , Measures.Quantity
            )
    

    这本身并不是一个答案,因为我还没有尝试过,而且我的MDX知识太老了,根本无法相信它会起作用。然而,正如推特上提到的,我想知道下面的方法是否行不通?具体来说,使用Time.Years.Members作为要平均的成员列表

    WITH
    SET     OrderedQuarters
    AS      Order(
              Time.Quarters.Members,
              Time.CurrentMember.Caption,
              BASC
            )
    SET     UniqueQuarters
    AS      Filter(
              OrderedQuarters,
              OrderedQuarters.Item(
                OrderedQuarters.CurrentOrdinal-1
              ).Caption <> Time.CurrentMember.Caption
            )
    MEMBER  Measures.QuantitySum
    AS      Sum(
              Filter(
                OrderedQuarters,
                UniqueQuarters.Item(
                  UniqueQuarters.CurrentOrdinal
                ).Caption = Time.CurrentMember.Caption
              )
            , Measures.Quantity
            )
    MEMBER  Measures.Counter
    AS      Count(
              Filter(
                OrderedQuarters,
                UniqueQuarters.Item(
                  UniqueQuarters.CurrentOrdinal
                ).Caption = Time.CurrentMember.Caption
              )
            )
    MEMBER  Measures.[Sum over Count]
    AS      Measures.QuantitySum / Measures.Counter
    MEMBER  Measures.AvgQuantity
    AS      Avg(
              Time.Years.Members
            , Measures.Quantity
            )
    SELECT {Measures.QuantitySum
           ,Measures.Counter
           ,Measures.[Sum over Count]
           ,Measures.AvgQuantity} ON COLUMNS
    ,       UniqueQuarters        ON ROWS
    FROM    SteelWheelsSales
    
    与
    预定宿舍
    作为命令(
    各位议员,
    Time.CurrentMember.Caption,
    巴斯克
    )
    设置唯一的四分之一
    作为过滤器(
    预定宿舍,
    订购的宿舍。物品(
    OrderedQuarter.CurrentOrderinal-1
    ).Caption Time.CurrentMember.Caption
    )
    成员度量.QuantitySum
    总之(
    滤器(
    预定宿舍,
    独一无二的四分之一。物品(
    UniqueQuarters.CurrentOrdinal
    ).Caption=Time.CurrentMember.Caption
    )
    数量
    )
    议员:反措施
    作为伯爵(
    滤器(
    预定宿舍,
    独一无二的四分之一。物品(
    UniqueQuarters.CurrentOrdinal
    ).Caption=Time.CurrentMember.Caption
    )
    )
    成员度量。[总数超过计数]
    AS Measures.QuantitySum/Measures.Counter
    成员Measures.AvgQuantity
    平均值(
    时间·年·成员
    数量
    )
    选择{Measures.QuantitySum
    ,措施
    ,度量值。[总和超过计数]
    ,Measures.AvgQuantity}在列上
    ,排成排的唯一四分之一
    来自Steelwheelsales
    
    独特的功能在蒙德里安是否起作用?如果将
    Measures.Quantity
    添加到行集合中,会发生什么?如果已使用聚合类型Sum定义,则在度量值
    成员度量值的定义中,它是否产生与
    [QuantitySum]
    相同的结果。如果将
    度量值.Quantity
    更改为
    度量值.QuantitySum
    ,会发生什么?(嗯……尝试转移到AdvWrks原型,但即使是您的初始基本脚本在AdvWrks中的行为也有很大不同-结果直接由Q1、Q2、Q3、Q4聚合)@whytheq感谢您的回复。Mondrian有不同的,但我不认为它有什么帮助,因为QTR1、QTR2等明显重复的事件并不重复,因为它们都属于不同的年份。我无法向行轴添加度量值。数量,因为您不能在多个轴上使用相同的层次结构。如果我使用Measures.QuantitySum在Measures.AvgQuantity的定义中,我得到的结果与Measures.QuantitySum相同-而不是平均值。W/re to AdvWrks:在我看来,这真的很奇怪。该多维数据集中的季度是否低于年份?因此,如果我理解正确,您使用的层次结构将唯一季度作为顶层?在这种情况下,实现正确的聚合是不可能的rivial。我的问题的重点是在一些数据(在我的例子中,我使用了标题)上进行汇总,这些数据与较低级别的成员相关,并且在整个级别上是非唯一的。@RolandBouman我的“答案”实际上只是一个大的评论-我想你可能对他们使用的结构感兴趣。
    MEMBER  Measures.AvgQuantity
    AS      Avg(
              Filter(
                OrderedQuarters,
                UniqueQuarters.Item(
                  UniqueQuarters.CurrentOrdinal
                ).Caption = Time.CurrentMember.Caption
              )
             * Time.Years.Members
            , Measures.Quantity
            )
    
    WITH
    SET     OrderedQuarters
    AS      Order(
              Time.Quarters.Members,
              Time.CurrentMember.Caption,
              BASC
            )
    SET     UniqueQuarters
    AS      Filter(
              OrderedQuarters,
              OrderedQuarters.Item(
                OrderedQuarters.CurrentOrdinal-1
              ).Caption <> Time.CurrentMember.Caption
            )
    MEMBER  Measures.QuantitySum
    AS      Sum(
              Filter(
                OrderedQuarters,
                UniqueQuarters.Item(
                  UniqueQuarters.CurrentOrdinal
                ).Caption = Time.CurrentMember.Caption
              )
            , Measures.Quantity
            )
    MEMBER  Measures.Counter
    AS      Count(
              Filter(
                OrderedQuarters,
                UniqueQuarters.Item(
                  UniqueQuarters.CurrentOrdinal
                ).Caption = Time.CurrentMember.Caption
              )
            )
    MEMBER  Measures.[Sum over Count]
    AS      Measures.QuantitySum / Measures.Counter
    MEMBER  Measures.AvgQuantity
    AS      Avg(
              Time.Years.Members
            , Measures.Quantity
            )
    SELECT {Measures.QuantitySum
           ,Measures.Counter
           ,Measures.[Sum over Count]
           ,Measures.AvgQuantity} ON COLUMNS
    ,       UniqueQuarters        ON ROWS
    FROM    SteelWheelsSales