MDX - 获取总和而不是单个值

时间:2015-09-02 14:35:23

标签: filter count ssas mdx

我的数据如下:

ID                                   |PersonID  |CompanyID  |DateID  |Throughput |AmountType
33F467AC-F35B-4F24-A05B-FC35CF005981 |7         |53         |200802  |3          |0
04EE0FF0-511D-48F5-AA58-7600B3A69695 |18        |4          |201309  |5          |0
AB058AA5-6228-4E7C-9469-55827A5A34C3 |25        |69         |201108  |266        |0

有大约一百万行。列名* ID指的是其他表,因此它们可以用作维度。

我有一个OLAP多维数据集,其中吞吐量为Measure,其余为维度。

我有一个应该计算Quartiles的MDX查询,这里描述并解决了查询的其他问题:Trying to calculate quartiles in MDX

当我用一年过滤时计算工作正常,但是当我用两年过滤时,结果是两年的总和。我用一个例子来证明。我已将查询简化为仅显示行计数,因为它仍然提供相同的问题。 MDX查询看起来像这一年:

WITH
SET selection as ({[Dates].[Year].&[2014]})
SET [NonEmptyIds] AS
 NonEmpty(
      [ThroughputID].[ID].[Id].ALLMEMBERS,
  {[Measures].[Throughput]} * [selection]
 )
 SET [ThroughputData] AS 
ORDER
    (    
        [NonEmptyIds],  
        [Measures].[Throughput], 
        BASC
     )
MEMBER [Measures].[RowCount] AS COUNT (ThroughputData)

SELECT
selection ON 0,
{[Measures].[RowCount]}
ON 1
FROM [Throughput]

上述查询的结果是:

         |2014
RowCount |116 979

如果我在2015年将选择部分更改为过滤:

SET selection as ({[Dates].[Year].&[2015]})

我得到了这个结果:

         |2015
RowCount |68 038

然后,如果我在2014年和2015年更改选择部分以进行过滤:

SET selection as ({[Dates].[Year].&[2014],[Dates].[Year].&[2015]})

我得到了这个结果:

         |2014    |2015
RowCount |185 017 |185 017

116 979 + 68 038 = 185 017,两年均显示各年的总和。

有谁知道我在查询中做错了什么?

3 个答案:

答案 0 :(得分:1)

我不明白你为什么用复杂的,基于MDX的方式计算这个,用会话定义的集合和度量(WITH ...)。为什么不简单地在多维数据集中创建一个基于COUNT的度量,来源于事实表的行,并将[Dates]维度切片呢?

然后你的MDX会简化为(例如):

SELECT 
Measures.[YourCountMeasure] ON 0,
[Dates].[Year].Members ON 1
FROM Throughput

按年份切片将在多维数据集中定义。

实际上,问题在于:

SET [NonEmptyIds] AS
 NonEmpty(
      [ThroughputID].[ID].[Id].ALLMEMBERS,
  {[Measures].[Throughput]} * [selection]
 )

这个集合定义一次。它使用set [selection](两年)。它不会在MDX查询中多次重新评估。您在查询的轴上有[日期]。[年]的单独成员的事实将不会使该成员重新计算该成员(“看,这个集合也在[日期]上定义。[年]层次结构 - 我最好将它切片并根据当前成员重新计算集合“)。该集仅评估一次。

像这样的简单COUNT量度可能有效:

WITH
MEMBER Measures.CountNonEmptyThings AS
COUNT(NonEmpty(
      [ThroughputID].[ID].[Id].ALLMEMBERS,
  [Measures].[Throughput]))
SELECT
Measures.CountNonEmptyThings ON 0,
[Dates].[Years].Members ON 1  -- or whatever set you like
FROM Throughput

这个重新计算你在轴上放置的多年中的每一年。

答案 1 :(得分:0)

当你有两年2014& 2015年集Selection,然后

 NonEmpty(
      [ThroughputID].[ID].[Id].ALLMEMBERS,
  {[Measures].[Throughput]} * {[Dates].[Year].&[2014], [Dates].[Year].&[2015]}
 )

以上是什么意思

给我一套2014年以及2015年非空的ID

由于每年对应的一组Ids是不同的(我猜),它们会被加起来!

由于您已经提供了代码示例,因此我对集合的使用没有任何意见,但您必须对代码进行相当多的修改才能获得当前计数。

WITH
SET selection as 
{
 [Dates].[Year].[Year].&[2015], 
 [Dates].[Year].[Year].&[2014]
}

MEMBER [Measures].[RowCount] AS 
COUNT (
        NonEmpty(
            [ThroughputID].[ID].[Id].ALLMEMBERS,
            [Measures].[Throughput]
                )
      )

SELECT
RowCount ON 0,
selection  ON 1
FROM [Throughput]

长话短说:由于集合是静态的,当前上下文不会改变它们的内容,因此它们不应该在计算中使用。

我上面所做的不是在我的计算中引用该集合,而是引用当前年份(在范围内)来获取Ids而不是将其放在另一个命名集合中(这也是静态的),把它放在在会员的计算中。

希望这有帮助。

答案 2 :(得分:0)

SEBTHU的回答对我来说没问题。我认为不需要在自定义度量中使用currentmember函数。

以下是针对AdvWrks多维数据集的等效脚本:

WITH 
  SET [YearSet] AS 
    {
      [Date].[Calendar Year].&[2007]
     ,[Date].[Calendar Year].&[2008]
    } 
  MEMBER [Measures].[RowCount] AS 
    Count
    (
      NonEmpty
      (
        [Customer].[Customer].[Customer]
       ,[Measures].[Internet Sales Amount]
      )
    ) 
SELECT 
  [Measures].[RowCount] ON 0
 ,[YearSet] ON 1
FROM [Adventure Works];

以上是返回的内容,即 not static:

enter image description here

您还可以使用SUM函数与IIF的组合来构建这样的计数度量 - 在某些情况下它可以很快:

WITH 
  SET [YearSet] AS 
    {
      [Date].[Calendar Year].&[2007]
     ,[Date].[Calendar Year].&[2008]
    } 
  MEMBER [Measures].[RowCount] AS 
    Count
    (
      NonEmpty
      (
        [Customer].[Customer].[Customer]
       ,[Measures].[Internet Sales Amount]
      )
    ) 
  MEMBER [Measures].[RowCountFAST] AS 
    Sum
    (
      [Customer].[Customer].[Customer]
     ,IIF
      (
         [Measures].[Internet Sales Amount] = 0
        ,null
        ,1
       )
    ) 
SELECT 
  {
    [Measures].[RowCount]
   ,[Measures].[RowCountFAST]
  } ON 0
 ,[YearSet] ON 1
FROM [Adventure Works];

上述结果:

enter image description here

此替代方法适用于您的方案:

WITH 
  MEMBER [Measures].[CountNonEmptyThings] AS 
    Sum
    (
      [ThroughputID].[ID].[Id]
     ,IIF
      (
        [Measures].[Throughput] = 0
       ,NULL
       ,1
      )
    ) 
SELECT 
  [Measures].[CountNonEmptyThings] ON 0
 ,[Dates].[Years].MEMBERS ON 1
FROM [Throughput];