我最近发布了一个关于如何让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级别有一个Dimension,而且我还添加了。[YTD]维度。
我确实注意到,如果我注释掉。[YTD]并取消注释[Product]维度,这是有效的,但我必须使用*而不是像这样的逗号。
[Product].[Color].[Color].MEMBERS*
//[Due Date].[Calendar Month].[All].[YTD],
[Due Date].[Calendar Month].[Calendar Month].MEMBERS
是否可以将产品维度包含在YTD和Calendar Month.MEMEBERS的行中?
答案 0 :(得分:6)
Greg对你的问题的回答很好,我只是想向你展示你查询的细节,这样你就可以更好地理解你如何使用MDX查询和立方体的结构产生你想要的结果。
首先,这是大多数MDX查询的基本结构:
SELECT
Set_Expression ON COLUMNS
,
Set_Expression ON ROWS
FROM CUBE;
(对MDX来说还有一点,但这可能是80-90%。)
集合表达式是一个返回集合的表达式 - 因此您可以看到理解集合是什么以及如何构建有效表达式,返回右集。
首先,又是什么? set 是-drum roll- .... set 的元组 1 。但不只是任何元组 - 只有具有相同维度层次结构的元组 (也称为维度)。让我们看一些潜在的表达式的例子,我会告诉你它们是否有效。
有一个元组的集合?的 VALID 强>
{ Product.Product.Laptop }
具有来自同一维度层次结构的两个元组的集合?的 VALID 强>
{ Product.Product.Laptop , Product.Product.Desktop }
具有来自相同维度层次结构但具有不同级别的两个元组的集合?的 VALID 强>
{ Date.DateHierarchy.Year.2008 , Date.DateHierarchy.Quarter.2009Q1 }
具有来自相同维度但具有不同层次结构的两个元组的集合?的 INVALID 强>
<击> 撞击>
{ Product.Product.[Laptop] , Product.Category.[Hardware] }
为什么这个无效?因为这两个元组具有不同的维度。如果你回想一下&#34; cube&#34;的字面比喻,每个维度层次结构都是&#34; face&#34;每个元组都是沿构成其维度的面的立方体切片(并且任何不是元组显式维度的一部分的维度层次结构都被视为隐式&#34;所有成员&# 34;在执行时)所以为了将两个或多个元组组合成一个集合 - 所以你可以在一个切片中从多维数据集中提取它们 - 它们必须都来自同一组面 - 相同的维度。
具有元组和设置函数(一个返回一组元组的MDX函数)的集合来自同一维度层次结构?的 VALID 强>
{
Tail ( Order ( Product.Product.Members, Measures.Profit, BASC ), 5),
Product.Product.All
}
具有来自相同维度层次结构的两个集合函数的集合?的 VALID 强>
{ Subset(Product.Product.Members,0,5), Subset(Product.Product,Members,6,5) }
带有二维元组的集合? 有效 但是!你必须在元组周围添加括号。 (你可以只用一个维度将元组括在元组周围,但它不是必需的。)
{ ( Product.Product.Laptop, Date.Year.2015 ) }
一组有两个元组,每个元组在相同的层级上有两个维度?的 VALID 强>
{
( Product.Product.Laptop, Date.Year.2015 ),
( Product.Product.Tablet, Date.Year.2013 )
}
(请注意,成员不必完全相同,只是层次结构。希望这是您认识到&#34;维度&#34;意味着什么的点。)
一个包含两个元组的集合,每个元组在相同的层级上具有两个维度但在元组内的顺序不同?的 INVALID 强>
<击> 撞击>
{ ( 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
现在了解这里发生的事情非常重要。我说'#34;结合集&#34;之前,但正如您在所有示例中看到的那样,您不能将具有不同维度的各组元组一起放入一个集合中。
那么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)
再一次,格雷格的回答实现了这一点。所以我希望我的帖子能解释 Greg的答案是如何实现的!
此外,这里有两种替代语法方法可以在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)
函数也是如此。正因为如此,您可以看到有多种语法方法可以实现相同的概念。
因此元组表达式(Product.Product.Laptop)
指向多维数据集中Product.Product
维度层次结构的成员为Product.Product.Laptop
的单元格集,而对于所有其他维度层次结构,该成员是默认值成员(如果它是All成员,则立方体基本上不做任何工作,因为在该维度层次结构上不需要切片。)
在下图中,您可以看到元组表达式(Time.[2nd half], Source.nonground.air)
如何应用于多维数据集以生成其坐标空间。
好的,回到顶部。
答案 1 :(得分:2)
试试这个:
NON EMPTY
{
[Product].[Color].[Color].MEMBERS*
{
[Due Date].[Calendar Month].[All].[YTD],
[Due Date].[Calendar Month].[Calendar Month].MEMBERS
}
} ON ROWS