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

MDX - Getting the sum instead of individual values

我的数据是这样的:

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 多维数据集,其中吞吐量列作为度量,其余列作为维度。

我有一个应该计算四分位数的 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,这两年都是各年的总和。

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

我不明白您为什么要以基于 MDX 的复杂方式使用会话定义的集合和度量(WITH...)来计算它。为什么不简单地在多维数据集中创建一个基于 COUNT 的度量,以您的事实 table 的行为来源,并让 [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 查询中多次重新评估。事实上,您在查询的轴上有 [Dates].[Years] 的单独成员,这不会使该集合为该成员重新计算 ("oh look, this set is also defined on the [Dates].[Years] hierarchy - I'd better slice it and recalculate the set based on the current member")。该集合仅评估一次。

像这样的简单 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

为您放在轴上的多年中的每一年重新计算。

当集合 Selection 中同时包含年份 2014 和 2015 时,则

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

以上是什么意思

给我一组 2014 年和 2015 年非空的 ID

由于每年对应的 ID 集是不同的(我猜),所以它们会被加起来!

由于您给出了示例代码,我对集合的用法没有任何意见,但您必须对代码进行大量修改才能获得当前计数。

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]

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

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

希望对您有所帮助。

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];

这就是上面的returns即不是静态的:

您还可以使用 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];

以上结果:

此替代方法适用于您的场景:

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];