【问题标题】:MDX: Filtering and slicing on different members of the same dimensionMDX:对同一维度的不同成员进行过滤和切片
【发布时间】:2014-01-03 20:12:06
【问题描述】:

我正在使用 icCube 的销售立方体来学习 MDX。我想编写一个 MDX 查询来显示 2010 年销售收入超过 80,000 美元的国家/地区的 2009 年销售收入。我尝试了以下方法,但它返回了一个只有一列([Amount])的空表:

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]

【问题讨论】:

    标签: filter mdx slice iccube


    【解决方案1】:

    随便用

    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 作品上尝试了类似的查询,它显示所有客户、澳大利亚、加拿大和美国,但不显示法国、德国和英国:

    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] 的所有数据...
    • @MeirGoldenberg 我使用 MS Adventure Works 验证了我的查询 - 根据需要进行了调整,请参阅我编辑的答案。我认为您的查询或数据有其他问题。
    • icCube 中有一个错误 :-( ,这就是为什么不工作
    【解决方案2】:

    更新:元组评估是我们错过的一个案例,该错误已在icCube 4.2 中修复。请注意,在 where 子句和轴上使用相同的层次结构很棘手。过滤掉任何集合:“{[2010],[2011]} on 0 .. 其中 [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:Categories

    它们允许创建一个层次结构作为其他层次结构的成员。您可以将这些国家/地区定义为 [80000+],然后根据此新分类执行计算。

    【讨论】:

    • 请指出我出错的地方,但在我看来,没有子查询的解决方案是完全错误的,因为查询的评估顺序是:FROM,WHERE,SELECT(套等)。一旦 WHERE 子句中的切片完成(因此只有 [2009] 的数据保留在多维数据集中),我就不能在 SELECT 子句中对 [2010] 使用过滤器。另请参阅此帖子:social.msdn.microsoft.com/Forums/sqlserver/en-US/…
    • MDX 中的 WHERE 子句与 SQL where 不同,更像是一种设置默认值的方式。因此,如果在轴上放置 [2010],您将使用 [2010] 覆盖 [2009]。当您使用子查询时,您会获得类似于 SQL WHERE 子句中的行为。这很奇怪,但这就是 MDX 的工作原理
    • 在我们几天后发布新版本之前,您必须使用静态集或带有子选择的查询(我的第二个帖子)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多