MDX:在同一维度的不同成员上进行过滤和切片

6

我正在使用icCube的销售多维立方体学习MDX。我想编写一个MDX查询来显示2010年销售额超过$80,000的那些国家在2009年销售的收入。我尝试了以下内容,但返回了只有一列([金额])的空表:

WITH
 SET [myset] AS Filter([Country].members, ([Measures].[Amount], [2010])>80000)
select [Country].members on 0, [Amount] on 1
from (select [myset] on 0, [Amount] on 1 from [sales])
where [2009]
2个回答

3

只需使用

WITH
 SET [myset] AS Filter([Country].members, ([Measures].[Amount], [2010])>80000)
select [myset] on 0, [Amount] on 1
from [sales]
where [2009]

在MDX中,这种类型的查询不需要子查询或WHERE。你甚至可以省略集合myset,直接写。
select Filter([Country].members, ([Measures].[Amount], [2010])>80000) on 0,
       [Amount] on 1
from [sales]
where [2009]

我在 Adventure works 上尝试了一个类似的查询,显示所有客户,包括澳大利亚、加拿大和美国,但不包括法国、德国和英国:

SELECT Filter([Customer].[Country].Members,
              ([Measures].[Internet Sales Amount], [Date].[Calendar Year].&[2006]) > 600000
             )
       ON 0,
       {[Measures].[Internet Sales Amount]}
       ON 1
FROM [Adventure Works]
WHERE [Date].[Calendar Year].&[2008]

这不起作用。它返回一个空表。我理解在 [2009] 上的切片会删除所有 [2010] 的数据... - AlwaysLearning
@MeirGoldenberg 我已经验证了我的查询,根据需要做了适当的修改,使用了微软的Adventure Works数据库,详见我的编辑答案。我猜想你的查询或数据可能还有其他问题。 - FrankPl
icCube 有一个 bug :-( ,所以它不能工作。 - ic3

2
更新:我们错过了元组评估的情况,已经在icCube 4.2中修复了该错误。请注意,在where子句和轴上使用相同的层次结构是棘手的。任何集合都将被过滤掉:“ {[2010],[2011]} on 0 .. where [2010]将返回[2010],但元组将在不过滤的情况下进行评估。同一维度的不同层次将应用autoexists过滤器。

由于这有点棘手,我们决定扩展SETS,允许在查询中声明一个使用全局上下文评估的集合 - 而不考虑where子句和子查询:

WITH
-- always the same regardless of the where clause and subquery
  STATIC SET [Global] Filter([Country].members, ([Measures].[Amount], [2010])>80000)
..

最简单和最有效的解决方案是按照Frank的建议,直接将筛选过的国家添加到轴上。
SELECT 
   // this will return the countries with sales amount bigger than 80'000 for [2010]
   // e.g. { [USA], [UK] } ... [2010] is is just used for filterting
   Filter([Country].members, ([Measures].[Amount], [2010])>80000) on 0,
   // When evaluated we're going to use [2009] as it's the slicer default value
   [Amount] on 1
FROM [sales]
WHERE [2009]

关于您的查询,它应该可以工作。我同意,这是icCube中的一个错误,我们将尽快修复它(PTS)。同时,您必须避免在切片器和用于切片器的筛选函数中使用相同的层次结构,例如:
WITH 
 MEMBER [Amount 2009] AS ([Amount],[2009])
SELECT 
  Filter([Country].members, ([Measures].[Amount], [2010])>80000) on 0,
  [Amount 2009] on 1
FROM [sales]

或者您可以切换到适用于icCube的版本(比Frank的版本效率低):
SELECT [Country].members on 0, [Amount] on 1
FROM (select  Filter([Country].members, ([Measures].[Amount], [2010])>80000) on 0 from [sales])
WHERE [2009]

如果您根据不同的标准进行分组,您可以使用icCube几个月前引入的新功能:分类
它们允许创建一个层次结构作为其他层次结构的成员。您可以将这些国家定义为[80000+],然后基于这个新的分类进行计算。

请指出我错在哪里,但在我看来,没有子查询的解决方案是错误的,因为查询的评估顺序是:FROM、WHERE、SELECT(集合等)。一旦在 WHERE 子句中完成了切片操作(因此仅剩下 [2009] 的数据),我就无法在 SELECT 子句中对 [2010] 进行过滤。请参阅此帖子:http://social.msdn.microsoft.com/Forums/sqlserver/en-US/cd980958-e443-444e-a176-9285d5080059/mdx-query-execution-and-context?forum=sqlanalysisservices - AlwaysLearning
MDX中的WHERE子句不像SQL中的WHERE子句,更像是设置默认值的一种方式。因此,如果在轴上放置了[2010],那么将使用[2010]来覆盖[2009]。只有在使用子查询时,才会出现类似SQL WHERE子句的行为。这很奇怪,但这就是MDX的工作方式。 - ic3
在几天内我们发布新版本之前,你必须使用静态集或者带有子查询的查询语句(这是我发帖中的第二个建议)。 - ic3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接