MDX/SSRS - 如何让“ALL”标签显示在报告中然后添加额外的维度
MDX/SSRS - how do you get the “ALL” label to display in a report then add additional dimensions
我最近 post 提出了一个关于如何让 ALL 标签出现在 SSRS 报告中的问题。 "whytheq" 非常友好 post 一个有效的例子。下面是带有附加维度的 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
是否可以将产品维度与 YTD 和日历一起包含在行中 Month.MEMEBERS?
试试这个:
NON EMPTY
{
[Product].[Color].[Color].MEMBERS*
{
[Due Date].[Calendar Month].[All].[YTD],
[Due Date].[Calendar Month].[Calendar Month].MEMBERS
}
} ON ROWS
Greg 对您的问题的回答很好,我只是想向您展示查询的具体细节,以便您更好地理解如何使用 MDX 查询和多维数据集的结构来生成您想要的结果.
首先,这是大多数 MDX 查询的基本结构:
SELECT
Set_Expression ON COLUMNS
,
Set_Expression ON ROWS
FROM CUBE;
(MDX 有点多,但这可能是 80-90%。)
一个 集合表达式 是一个 returns 集合的表达式 - 所以你可以看到理解集合是什么以及如何构建一个 有效 returns 正确 集的表达式。
那么首先,什么是集合?一个集合是-drum roll- ....一个集合的元组1。但不仅仅是任何元组 - 只有具有相同维度层次结构的元组(也称为维度) .让我们看一些潜在的集合表达式的例子,我会告诉你它们是否有效。
一个元组的集合? 有效.
{ Product.Product.Laptop }
一个包含来自同一维度层次结构的两个元组的集合? 有效.
{ Product.Product.Laptop , Product.Product.Desktop }
一个包含来自相同维度层次结构但不同级别的两个元组的集合? 有效.
{ Date.DateHierarchy.Year.2008 , Date.DateHierarchy.Quarter.2009Q1 }
一个包含来自同一维度但不同层次结构的两个元组的集合? 无效.
{ Product.Product.[Laptop] , Product.Category.[Hardware] }
为什么这个无效?因为这两个元组具有不同的维度。如果您回想一下 "cube" 的字面隐喻,每个维度层次结构都是一个 "face",每个元组都是立方体的一部分,沿着构成其维度的面(以及任何维度层次结构是元组的显式维度的一部分在执行时被视为隐式 "All members")因此,为了将两个或多个元组组合成一个集合 - 这样您就可以在单个切片中从立方体中提取它们 - 他们必须都来自同一组面孔 - 相同的维度。
具有元组的集合和来自相同维度层次结构的 集合函数 (一个 MDX 函数,其中 returns 一组元组)? 有效.
{
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 )
}
(请注意,成员不必完全相同,只需层次结构即可。希望这是您认识到 "dimensionality" 含义的关键。)
一个包含两个元组的集合,每个元组在相同的层次级别上都有两个维度,但在元组中的顺序不同? 无效
{
( 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
现在了解这里发生的事情很重要。我之前说过 "combine sets",但是正如您在所有示例中看到的那样,您不能只是将具有不同维度的各种元组集合放入一个集合中。
那么 CrossJoin 在做什么?
好吧,给定
的 CrossJoin
{Set With Tuple Dimensionality (A)} * {Set with Tuple Dimensionality (B)}
结果集的元组维度为 (A, B)
。
所以回顾我们的CrossJoin例子,我们的left-hand边只有一个元组,它的维度是(Product.Product)
。而我们的 right-hand 端有许多维度为 (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 点写了这么长的 post:你的错误是从根本上误解了 MDX 中集合的概念,而不仅仅是语法错误。
显然您希望最终集合的元组的维度层次结构是
(Product.Color, Due Date.Calendar Month)
再一次,格雷格的回答实现了这一点。所以我真的希望我的post已经解释了如何格雷格的回答实现了这一点!
此外,这里有两种替代语法方法可以在 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)
函数也是如此。只是为了让您看到有多种句法方式可以实现相同的概念。
- 快速复习元组:多维数据集中的每个单元格代表一组唯一的维度层次结构成员。 元组 是一组维度层次结构成员,它们构成了立方体中的一组单元格(或坐标space)。 (N.B.:任何未在元组表达式中明确命名的维度层次结构都使用其 默认成员 ,如果未在元组表达式中明确设置SSAS 多维数据集模型是 All 成员。)
所以元组表达式 (Product.Product.Laptop)
指向多维数据集中的单元集,其中 Product.Product
维度层次结构的成员是 Product.Product.Laptop
,对于所有其他维度层次结构,该成员是默认成员(如果它是 All 成员,则多维数据集基本上不做任何工作,因为在该维度层次结构上不需要切片。)
在下图中,您可以看到如何将元组表达式 (Time.[2nd half], Source.nonground.air)
应用于立方体以生成其坐标 space。
好的,回到顶部。
我最近 post 提出了一个关于如何让 ALL 标签出现在 SSRS 报告中的问题。 "whytheq" 非常友好 post 一个有效的例子。下面是带有附加维度的 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
是否可以将产品维度与 YTD 和日历一起包含在行中 Month.MEMEBERS?
试试这个:
NON EMPTY
{
[Product].[Color].[Color].MEMBERS*
{
[Due Date].[Calendar Month].[All].[YTD],
[Due Date].[Calendar Month].[Calendar Month].MEMBERS
}
} ON ROWS
Greg 对您的问题的回答很好,我只是想向您展示查询的具体细节,以便您更好地理解如何使用 MDX 查询和多维数据集的结构来生成您想要的结果.
首先,这是大多数 MDX 查询的基本结构:
SELECT
Set_Expression ON COLUMNS
,
Set_Expression ON ROWS
FROM CUBE;
(MDX 有点多,但这可能是 80-90%。)
一个 集合表达式 是一个 returns 集合的表达式 - 所以你可以看到理解集合是什么以及如何构建一个 有效 returns 正确 集的表达式。
那么首先,什么是集合?一个集合是-drum roll- ....一个集合的元组1。但不仅仅是任何元组 - 只有具有相同维度层次结构的元组(也称为维度) .让我们看一些潜在的集合表达式的例子,我会告诉你它们是否有效。
一个元组的集合? 有效.
{ Product.Product.Laptop }
一个包含来自同一维度层次结构的两个元组的集合? 有效.
{ Product.Product.Laptop , Product.Product.Desktop }
一个包含来自相同维度层次结构但不同级别的两个元组的集合? 有效.
{ Date.DateHierarchy.Year.2008 , Date.DateHierarchy.Quarter.2009Q1 }
一个包含来自同一维度但不同层次结构的两个元组的集合? 无效.
{ Product.Product.[Laptop] , Product.Category.[Hardware] }
为什么这个无效?因为这两个元组具有不同的维度。如果您回想一下 "cube" 的字面隐喻,每个维度层次结构都是一个 "face",每个元组都是立方体的一部分,沿着构成其维度的面(以及任何维度层次结构是元组的显式维度的一部分在执行时被视为隐式 "All members")因此,为了将两个或多个元组组合成一个集合 - 这样您就可以在单个切片中从立方体中提取它们 - 他们必须都来自同一组面孔 - 相同的维度。
具有元组的集合和来自相同维度层次结构的 集合函数 (一个 MDX 函数,其中 returns 一组元组)? 有效.
{
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 )
}
(请注意,成员不必完全相同,只需层次结构即可。希望这是您认识到 "dimensionality" 含义的关键。)
一个包含两个元组的集合,每个元组在相同的层次级别上都有两个维度,但在元组中的顺序不同? 无效
{
( 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
现在了解这里发生的事情很重要。我之前说过 "combine sets",但是正如您在所有示例中看到的那样,您不能只是将具有不同维度的各种元组集合放入一个集合中。
那么 CrossJoin 在做什么?
好吧,给定
的 CrossJoin {Set With Tuple Dimensionality (A)} * {Set with Tuple Dimensionality (B)}
结果集的元组维度为 (A, B)
。
所以回顾我们的CrossJoin例子,我们的left-hand边只有一个元组,它的维度是(Product.Product)
。而我们的 right-hand 端有许多维度为 (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 点写了这么长的 post:你的错误是从根本上误解了 MDX 中集合的概念,而不仅仅是语法错误。
显然您希望最终集合的元组的维度层次结构是
(Product.Color, Due Date.Calendar Month)
再一次,格雷格的回答实现了这一点。所以我真的希望我的post已经解释了如何格雷格的回答实现了这一点!
此外,这里有两种替代语法方法可以在 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)
函数也是如此。只是为了让您看到有多种句法方式可以实现相同的概念。
- 快速复习元组:多维数据集中的每个单元格代表一组唯一的维度层次结构成员。 元组 是一组维度层次结构成员,它们构成了立方体中的一组单元格(或坐标space)。 (N.B.:任何未在元组表达式中明确命名的维度层次结构都使用其 默认成员 ,如果未在元组表达式中明确设置SSAS 多维数据集模型是 All 成员。)
所以元组表达式 (Product.Product.Laptop)
指向多维数据集中的单元集,其中 Product.Product
维度层次结构的成员是 Product.Product.Laptop
,对于所有其他维度层次结构,该成员是默认成员(如果它是 All 成员,则多维数据集基本上不做任何工作,因为在该维度层次结构上不需要切片。)
在下图中,您可以看到如何将元组表达式 (Time.[2nd half], Source.nonground.air)
应用于立方体以生成其坐标 space。
好的,回到顶部。