MDX YTD 超出范围 (:)

MDX YTD over range (:)

YTD 可以处理日期范围吗?

我正在尝试将今年 X 天的时间段与上一年的同期时间段进行比较。

我的 MDX 查询如下所示:

WITH MEMBER [Measures].[Prior YTD Amount] AS SUM
(
   YTD
   (
      ParallelPeriod
      (
         [Date].[Year],
         1,
         [Date].CurrentMember
      )
   )
   ,
   [Measures].[Amount]
)
set [ColSet] as
{
   [Measures].[Amount],
   [Measures].[Prior YTD Amount]
}
set [RowSet] as
{
   [Motif].[Categorie].Members
}
SELECT
NON EMPTY [ColSet] ON COLUMNS,
NON EMPTY [RowSet] ON ROWS
FROM [Things]
WHERE
{
   [Date].[2015].[2].[1]:[Date].[2015].[2].[9]
}

我正在使用 Mondrian 3.6。

简而言之,这段代码是行不通的。原因是以下代码行正在寻找您已将 Currentmember 应用于的层次结构的单个成员:

[Date].CurrentMember

集合中有不止一个成员[Date].[2015].[2].[1]:[Date].[2015].[2].[9]


这里是上面的一个小证明:

这个脚本:

WITH 
  MEMBER [Measures].[x] AS 
    [Date].[Calendar].CurrentMember.Member_Key 
SELECT 
  {[Product].[Category].[All Products]} ON 0
 ,{[Measures].[x]} ON 1
FROM [Adventure Works]
WHERE 
  {
      [Date].[Calendar].[Date].&[20080322]
  };

Returns这个:

而这个脚本:

WITH 
  MEMBER [Measures].[x] AS 
    [Date].[Calendar].CurrentMember.Member_Caption 
SELECT 
  {[Product].[Category].[All Products]} ON 0
 ,{[Measures].[x]} ON 1
FROM [Adventure Works]
WHERE 
  {
      [Date].[Calendar].[Date].&[20080322]
    : 
      [Date].[Calendar].[Date].&[20080323]
  };

Returns这个:

错误信息:


AdvWrks 中,我刚刚写了以下内容,如果您可以将目标日期范围从 WHERE 子句移动到命名集,这可能会有所帮助。

工作原理:

1.Finds 通过 .Item(0).Item(0)
命名的集合中的第一个日期 2.Finds 通过 .Item([myStartDates].Count - 1).Item(0)
命名集合中的最后一个日期 3.The 使用找到的两个日期创建一个平行的范围

WITH 
  SET [myStartDates] AS 
    {
        [Date].[Calendar].[Date].&[20080322]
      : 
        [Date].[Calendar].[Date].&[20080323]
    } 
  SET [parallelToFirst] AS 
    ParallelPeriod
    (
      [Date].[Calendar].[Calendar Year]
     ,1
     ,[myStartDates].Item(0).Item(0)
    ) 
  SET [parallelToLast] AS 
    ParallelPeriod
    (
      [Date].[Calendar].[Calendar Year]
     ,1
     ,[myStartDates].Item(
      [myStartDates].Count - 1).Item(0)
    ) 
  SET [Rebuild] AS 
    [parallelToFirst].Item(0) : [parallelToLast].Item(0) 
SELECT 
  {} ON COLUMNS
 ,[Rebuild] ON ROWS
FROM [Adventure Works];

然后很容易对该范围求和并将其弹出到日期维度:

WITH 
  SET [myStartDates] AS 
    {
        [Date].[Calendar].[Date].&[20080322]
      : 
        [Date].[Calendar].[Date].&[20080323]
    } 
  SET [parallelToFirst] AS 
    ParallelPeriod
    (
      [Date].[Calendar].[Calendar Year]
     ,1
     ,[myStartDates].Item(0).Item(0)
    ) 
  SET [parallelToLast] AS 
    ParallelPeriod
    (
      [Date].[Calendar].[Calendar Year]
     ,1
     ,[myStartDates].Item(
      [myStartDates].Count - 1).Item(0)
    ) 
  SET [ParallelRange] AS 
    [parallelToFirst].Item(0) : [parallelToLast].Item(0) 
  MEMBER [Date].[Calendar].[parallelSum] AS 
    Sum([ParallelRange]) 
SELECT 
  {
    [myStartDates]
   ,[ParallelRange]
   ,[Date].[Calendar].[parallelSum]
  } ON 0
 ,{
    [Measures].[Internet Sales Amount]
   ,[Measures].[Internet Order Quantity]
  } ON 1
FROM [Adventure Works];

这是结果(只是为了证明它正在做我们想要的):

下面是使用 ParallelPeriods 函数的替代方法。 我假设您在立方体中拥有上一年的所有日期,即 "gaps" 之间没有缺失的日期。如果是这样,您可以使用 LAG 函数跳转到 365 天(1 年)后的日期。此外,最初将当年的日期放在一个集合中。这样您就可以轻松地对它们进行参数化。

您的最终 MDX 应该类似于:

with set Dates as
{
  [Date].[2015].[2].[1]
  :
  [Date].[2015].[2].[9]
}//<<This can be also written as 
 //StrToSet("{[Date]."+ @DateStart + ":" +  "[Date]."+ @DateEnd + "}")
//@Date1 and @Date2 being the parameters you can pass from front end

set datesPrevYear as
{
  head(Dates, 1).item(0).LAG(365).item(0) \<<Gets the starting date's 1 year previous date
  : 
  tail(Dates, 1).item(0).LAG(365).item(0) \<<Gets the ending date's 1 year previous date
} 

member [Measures].[Prior YTD Amount] as
sum(datesPrevYear, [Measures].[Amount])

set [ColSet] as
{
  [Measures].[Amount],
  [Measures].[Prior YTD Amount]
}
set [RowSet] as
{
  [Motif].[Categorie].Members
}

select
non empty [ColSet] on columns,
non empty [RowSet] on rows
from [Things]