MDX计算的度量,它使不同值的总和

时间:2016-01-21 11:03:03

标签: sql-server ssas mdx business-intelligence analysis

我有一个奇怪的问题,我试图解决。我的事实表如下:

CaseID | ClientID | PaymentDate|ToPay   | Paid
1      |     1    | 2015-01-01 |1000    |100
1      |     1    | 2015-02-01 |1000    |200
1      |     1    | 2015-03-01 |1000    |300
2      |     1    | 2015-01-01 |2000    |100
2      |     1    | 2015-02-01 |2000    |400
2      |     1    | 2015-03-01 |2000    |150

我要做的是制定两项措施:
Sum(ToPay)
Sum(Paid)

有什么问题?

在结果集中我应该得到这样的值: 客户:1到付:3000,付:1250

这意味着sum(ToPay)将被计算为特定客户和案例的不同值。

可以在MDX中创建此类查询吗?如果是,那么如何?

2 个答案:

答案 0 :(得分:0)

好的 - 我尝试使用MS多维数据集AdvWrks

对您的情况进行建模

以下是所有情况总结的情况:

WITH 
  MEMBER [Date].[Calendar].[All].[x] AS 100 
  MEMBER [Date].[Calendar].[All].[y] AS 200 
  MEMBER [Date].[Calendar].[All].[z] AS 200 
  SET [blah] AS 
    {
      [x]
     ,[y]
     ,[z]
    } 
  MEMBER [Measures].[xx] AS 
    Sum
    (
      [blah]
     ,[Measures].[Internet Sales Amount]
    ) 
SELECT 
  {[Measures].[xx]} ON 0
FROM [Adventure Works];

结果是500。

要提取我使用Filter的唯一不同值的总和,它取决于设置的顺序,因此还需要使用Order函数:

WITH 
  MEMBER [Date].[Calendar].[All].[a] AS 100 
  MEMBER [Date].[Calendar].[All].[x] AS 50 
  MEMBER [Date].[Calendar].[All].[y] AS 200 
  MEMBER [Date].[Calendar].[All].[z] AS 200 
  SET [blah] AS 
    {
      [a]
     ,[x]
     ,[y]
     ,[z]
    } 
  MEMBER [Measures].[xx] AS 
    Sum
    (
      Filter
      (
        Order
        (
          [blah]
         ,[Measures].[Internet Sales Amount]
        ) AS x
       ,
          (
            x.CurrentMember
           ,[Measures].[Internet Sales Amount]
          )
        <> 
          (
            x.Item(
            x.CurrentOrdinal)
           ,[Measures].[Internet Sales Amount]
          )
      )
     ,[Measures].[Internet Sales Amount]
    ) 
SELECT 
  {[Measures].[xx]} ON 0
FROM [Adventure Works];

结果是350。

答案 1 :(得分:0)

如果你确实接受了Greg Galloway的建议,那对你很有帮助。否则,另一个好的MDX挑战!

这是你可以做的。

首先按照自然顺序对集合进行排序。

接下来,仅对那些集合中的当前成员与前一成员不同或者如果它是第一个成员的情况计算度量[To Pay](在这种情况下,当前的成员总是不会与以前的会员相同)

with set [Client&Case] as
order
     (
        [Fact].[ClientID].[All].children * [Fact].[CaseID].[All].children,
        [Fact].[ClientID].currentmember.name + "" + [Fact].[CaseID].currentmember.name
     )


member measures.[Actual - To Pay]  as 
sum
    (
     [Client&Case],
      iif
      (    
        not([Client&Case].item([Client&Case].currentordinal-1) is [Client&Case].item([Client&Case].currentordinal-2)) 
           --current not same not as previous
        or [Client&Case].currentordinal = 1 --the first member!
       ,[Measures].[To Pay]
       ,0
      )
    )

select 
{measures.[Paid], measures.[Actual - To Pay]} on 0,
[Client&Case] on 1
from [Your Cube]

来自Adventure Works:

    with set [Category&Country] as
    {
    ([Product].[Category].&[3], [Customer].[Customer Geography].[Country].&[Australia]),
    ([Product].[Category].&[3], [Customer].[Customer Geography].[Country].&[Australia]),
    ([Product].[Category].&[4], [Customer].[Customer Geography].[Country].&[Australia]),
    ([Product].[Category].&[4], [Customer].[Customer Geography].[Country].&[Australia]),
    ([Product].[Category].&[4], [Customer].[Customer Geography].[Country].&[Australia])
    }

    member measures.TotalInternetSales as
    sum([Category&Country],[Measures].[Internet Sales Amount])

    member measures.[ActualInternetSales]  as 
    sum
        (
         [Category&Country],
          iif
          (         
            not([Category&Country].item([Category&Country].currentordinal-1) is [Category&Country].item([Category&Country].currentordinal-2)) 
            or [Category&Country].currentordinal = 1
           ,([Category&Country].currentmember, [Measures].[Internet Sales Amount])
           ,0
          )
        )

    select 
    {measures.TotalInternetSales, measures.[ActualInternetSales]} on 0
    from [Adventure Works]

希望它有效。