【问题标题】:MDX/SSRS - how do you get the “ALL” label to display in a report then add additional dimensionsMDX/SSRS - 如何让“ALL”标签显示在报告中,然后添加其他维度
【发布时间】:2015-12-30 05:19:03
【问题描述】:

我最近发布了一个关于如何让 ALL 标签出现在 SSRS 报告中的问题。 “whytheq”很友好地发布了一个有效的例子。下面是带有一个附加维度的 MDX,如果我取消注释它会给我一个错误:

查询 (8, 5) 函数中指定的两个集合具有不同的维度。

WITH 
  MEMBER [Due Date].[Calendar Month].[All].[YTD] AS 
    [Due Date].[Calendar Month].[All] 
SELECT 
  NON EMPTY 
    {[Measures].[Freight]} ON COLUMNS
 ,NON EMPTY 
    {
      //[Product].[Color].[Color].MEMBERS*
      [Due Date].[Calendar Month].[All].[YTD],
      [Due Date].[Calendar Month].[Calendar Month].MEMBERS

    } ON ROWS
FROM [Adventure Works Cube];

我知道我有一个 .MEMBERS 级别的维度,并且我还添加了 .[YTD] 维度。

我确实注意到,如果我注释掉 .[YTD] 并取消注释 [Product] 维度,这是可行的,但我必须使用 * 而不是像这样的逗号。

      [Product].[Color].[Color].MEMBERS*
      //[Due Date].[Calendar Month].[All].[YTD],
      [Due Date].[Calendar Month].[Calendar Month].MEMBERS

是否可以将 Product 维度与 YTD 和 Calendar Month.MEMEBERS 一起包含在行中?

【问题讨论】:

  • 强烈建议您阅读此technet.microsoft.com/en-us/library/aa216769(v=sql.80).aspx,直到您了解元组、成员和集合之间的差异,以及 MDX 查询的每个部分生成的差异。
  • 嘿,除了我的回答,我只是想纠正你一点:为了让 All 成员除了层次结构的成员之外也显示出来,只需拉出层次结构的根成员级别本身,而不是属性级别。所以[Due Date].[Calendar Month].Members 而不是[Due Date].[Calendar Month].[Calendar Month].MEMBERS

标签: mdx ssrs-2008-r2


【解决方案1】:

Greg 对您的问题的回答很好,我只是想向您展示查询的具体细节,以便您更好地了解如何使用 MDX 查询和多维数据集的结构来产生您想要的结果。

首先,这是大多数 MDX 查询的基本结构:

    SELECT 
      Set_Expression ON COLUMNS
     ,
        Set_Expression ON ROWS
    FROM CUBE;

(MDX 有更多,但这可能是 80-90%。)

set 表达式 是一个返回集合的表达式 - 所以你可以看到理解集合是什么以及如何构建一个 valid 表达式非常重要返回 right 集合。

首先,什么是集合?一个 set 是 -drum roll- .... 一个 set 元组1。但不仅仅是任何元组 - 只有具有相同维度层次结构的元组(也称为维度)。让我们看一些潜在集合表达式的例子,我会告诉你它们是否有效。

带有一个元组的集合? 有效

{ Product.Product.Laptop }

具有来自同一维度层次结构的两个元组的集合? 有效

{ Product.Product.Laptop , Product.Product.Desktop }

具有来自相同维度层次结构但不同级别的两个元组的集合? 有效

{ Date.DateHierarchy.Year.2008 , Date.DateHierarchy.Quarter.2009Q1 }

具有来自同一维度但层次结构不同的两个元组的集合? 无效

{ Product.Product.[Laptop] , Product.Category.[Hardware] }

为什么这无效?因为这两个元组有不同的维度。如果你回想一下“立方体”的字面隐喻,每个维度层次结构都是一个“面”,每个元组都是沿着构成其维度的面的立方体的一个切片(以及任何不属于它的维度层次结构)元组的显式维度在执行时被视为隐含的“所有成员”)因此,为了将两个或多个元组组合成一个集合 - 这样您就可以从单个切片中的多维数据集中提取它们 - 它们都必须来自同一个一组面孔 - 相同的维度。

具有元组的集合和 set 函数(返回一组元组的 MDX 函数)来自同一维度层次结构? 有效

{ 
  Tail ( Order ( Product.Product.Members, Measures.Profit, BASC ), 5), 
  Product.Product.All 
}

具有来自同一维度层次结构的两个集合函数的集合? 有效

{   Subset(Product.Product.Members,0,5), Subset(Product.Product,Members,6,5) }

带有二维元组的集合? 有效 但是!您必须在元组周围加上括号。 (您可以在只有一维的元组周围加上括号,但这不是必需的。)

{ ( Product.Product.Laptop, Date.Year.2015 ) }

一个包含两个元组的集合,每个元组都有两个维度,分别位于相同的层次结构级别? 有效

{ 
  ( Product.Product.Laptop, Date.Year.2015 ),
  ( Product.Product.Tablet, Date.Year.2013 ) 
} 

(请注意,成员不必完全一样,只需层次结构即可。希望这是您认识“维度”含义的关键。)

具有两个元组的集合,每个元组具有两个维度,位于相同的相应层次结构级别,但在元组中的顺序不同? 无效

{
      ( Product.Product.Laptop, Date.Year.2015 ),
      ( Date.Year.2013, Product.Product.Tablet )
    }

(与 SQL 中的 UNION 相比 - 您必须具有一致的顺序,以便 MDX 可以构建设置以执行其他任务,例如在查询轴上正确嵌套元组的每个成员。)

最后,如果我们想将来自不同维度层次结构的两个集合组合成一个集合,我们可以使用方便的 CrossJoin 函数:

CrossJoin ( { Product.Product.Laptop } , Date.Year.Members )

正如您所发现的,您还可以使用星号 (*) 执行两个集合的交叉连接

Product.Product.Laptop * Date.Year.Members

现在了解这里发生了什么很重要。我之前说过“组合集合”,但是正如您在所有示例中看到的那样,您不能只是将具有不同维度的各种元组集合放在一个集合中。

那么,CrossJoin 是做什么的?

好吧,给定一个CrossJoin

 {Set With Tuple Dimensionality (A)} * {Set with Tuple Dimensionality (B)}

结果集的元组维度为(A, B)

所以回顾我们的 CrossJoin 示例,我们的左侧只有一个元组,其维度为 (Product.Product)。我们的右手边有许多元组(Date.Year 层次结构的每个成员),维数为(Date.Year)。所以我们最后的一组元组将有(Product.Product, Date.Year)的维度。

假设我们的立方体中每年都有 2010-2015 年,我们的最终集合将是 6 个元组

{ 
  ( Product.Product.Laptop, Date.Year.2010),
  ( Product.Product.Laptop, Date.Year.2011),
  ( Product.Product.Laptop, Date.Year.2012),
  ( Product.Product.Laptop, Date.Year.2013),
  ( Product.Product.Laptop, Date.Year.2014),
  ( Product.Product.Laptop, Date.Year.2015)
}

所以理论上你可以在这个集合中添加更多的元组,只要它们是具有相同维度的 simpatico - 例如,(Product.Product.Tablet, Date.Year.2013)

所以这也是一个 VALID 集合表达式:

{ 
 Product.Product.Laptop * Date.Year.Members, 
(Product.Product.Tablet, Date.Year.2013)`
}

所以现在回到你的问题,如果我们取消注释你损坏的代码行,我们会看到你有

{
  [Product].[Color].[Color].MEMBERS *
  [Due Date].[Calendar Month].[All].[YTD],
  [Due Date].[Calendar Month].[Calendar Month].MEMBERS
}

所以,这里有一组元组

[Product].[Color].[Color].MEMBERS *
      [Due Date].[Calendar Month].[All].[YTD]

其元组的维数为

(Product.Color, Due Date.Calendar Month)

然后你试图将另一组元组添加到这个集合中

[Due Date].[Calendar Month].[Calendar Month].MEMBERS

其元组的维度为

(Due Date.Calendar Month)

现在你明白你收到的错误信息了吗?

这让我明白了我为什么在凌晨 1 点写这篇很长的帖子:你的错误是从根本上误解了 MDX 中的集合概念的错误,而不仅仅是语法错误。

显然你希望你的最终集合的元组的维度层次结构是

(Product.Color, Due Date.Calendar Month)

再一次,格雷格的回答实现了这一点。所以我真的希望我的帖子已经解释了格雷格的回答是如何实现这一点的!

另外,这里有两种替代的语法方法可以在 COLUMNS 轴上实现您想要的相同集合结果:

NON EMPTY { ([Product].[Color].[Color].Members, [Due Date].[Calendar Month].Members ) }

NONEMPTY ( [Product].[Color].[Color].Members, [Due Date].[Calendar Month].Members )

基本上,(set, set) 语法也执行交叉连接,NONEMPTY(set1, set2) 函数也是如此。这样您就可以看到有多种语法方法可以实现相同的概念。


  1. 元组快速复习:多维数据集中的每个单元格代表一组唯一的维度层次结构成员。 tuple 是一组维度层次结构成员,它们构成多维数据集中的一组单元(或 坐标空间)。 (注意:任何未在元组表达式中明确命名的维度层次结构都使用其默认成员,如果未在 SSAS 多维数据集模型中明确设置,则为 All强>成员。)

因此元组表达式(Product.Product.Laptop) 指向多维数据集中的单元集,其中Product.Product 维度层次结构的成员为Product.Product.Laptop,对于所有其他维度层次结构,该成员是默认成员(如果它是All成员,多维数据集基本上不做任何工作,因为在该维度层次结构上不需要切片。)

在下图中,您可以看到元组表达式(Time.[2nd half], Source.nonground.air) 如何应用于立方体以生成其坐标空间。

好的,回到顶部。

【讨论】:

  • 很好的解释 - 我不得不问:这是一个笑话“MDX 还有一点,但这可能是 80-90%”?我认为一个简单的mdx 脚本(如您最初的 sn-p)看起来像一个 sql 脚本的方式是 80-90% 的问题!
  • @whytheq 与其说是玩笑不如说是手舞足蹈。与 SQL 类似的 MDX 更多的是关于概念化而不是语法。
  • 另外,我希望有人在我学习 MDX 的时候为我写过类似的东西——我一直在想我可以用自己的语法来找到正确的查询!
  • 你说得对,Kyle - 了解 mdx 的基础知识以用作更复杂脚本的构建块非常重要。 [MDX vs SQL] 就像 [Chess vs Chequers] ....
  • 很棒的答案。赞成。到处苦苦挣扎的 MDX 抛投者感谢您的时间@KyleHale
【解决方案2】:

试试这个:

NON EMPTY 
    {
      [Product].[Color].[Color].MEMBERS*
      {
       [Due Date].[Calendar Month].[All].[YTD],
       [Due Date].[Calendar Month].[Calendar Month].MEMBERS
      }

    } ON ROWS

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    相关资源
    最近更新 更多