如何通过同一层次结构中的多个项过滤Filter函数中的度量

时间:2015-02-13 14:15:32

标签: mdx

我正在创建一个生成MDX个查询的应用程序。当用户使用Filter函数时,我坚持实现一个场景,并且在逻辑表达式中,用户希望通过同一层次结构中的多个成员对度量进行切片。

这是一个真实的例子:有一个多维数据集教育,其中包含以下维度和度量

  • 维度:学生,学年
  • 措施:学生出勤,学生违规行为

用户希望在2010和2011学年看到有一个或多个学生违规行为的学生出勤。

我需要使用Filter函数完成此操作,因此我编写了下面的查询

SELECT [Measures].[Student Attendance] ON COLUMNS
FROM (
  SELECT 
    FILTER(
        [Student].[Student].[Student].Members, 
          (
            [Measures].[Student Infractions], 
            AGGREGATE(
                {
                  [School Year].[School Year].&[2010]
                 ,[School Year].[School Year].&[2011]
                }
            )
          ) > 1
    ) ON COLUMNS
  FROM [Education]
)

问题是当执行此查询时,它会抛出 'Query (4, 55) The Tuple function expects a tuple set expression for the 2 argument. A string or numeric expression was used.'

看起来在Filter函数中使用Aggregate函数是不可能的。有没有办法让查询工作?

3 个答案:

答案 0 :(得分:2)

你有一个额外的方括号,如下所示,它是元组第二个参数的一部分 - 这可能是错误信息的原因:

SELECT [Measures].[Student Attendance] ON COLUMNS
FROM (
  SELECT 
    FILTER(
        [Student].[Student].[Student].Members, 
          (
            [Measures].[Student Infractions], 
            AGGREGATE(
                {
                  [School Year].[School Year].&[2010]
                 ,[School Year].[School Year].&[2011]]   //<<<EXTRA BRACKET !
                }
            )
          ) > 1
    ) ON COLUMNS
  FROM [Education]
)

所有逻辑都可以放在外部查询的WHERE子句中去掉sub-select

SELECT [Measures].[Student Attendance] ON COLUMNS
FROM   [Education]
WHERE  (
        Filter
          (
            [Student].[Student].[Student].MEMBERS
           ,
              AGGREGATE(
                 {[School Year].[School Year].&[2010] , [School Year].[School Year].&[2011]}
                 ,[Measures].[Student Infractions]    
          )
        > 1
       );

修改

您没有AGGREGATE的原始查询,但针对AdvWrks进行了测试,似乎执行正常:

SELECT 
  [Measures].[Student Attendance] ON COLUMNS
FROM 
(
  SELECT 
      Filter
      (
        [Student].[Student].[Student].MEMBERS
       ,
          [Measures].[Student Infractions]
        * 
          ([School Year].[School Year].&[2010] + [School Year].[School Year].&[2011])
      )
    > 1 ON COLUMNS
  FROM [Education]
);

这是我写的AdvWrks等效脚本 - 运行正常:

SELECT 
  [Measures].[Internet Sales Amount] ON 0
FROM 
(
  SELECT 
    Filter
    (
      [Product].[Product Categories].[Subcategory].MEMBERS
     ,
          [Measures].[Reseller Order Quantity]
        * 
          (
            [Date].[Calendar].[Calendar Year].&[2007]
          + 
            [Date].[Calendar].[Calendar Year].&[2008]
          )
      > 1
    ) ON 0
  FROM [Adventure Works]
);

<强> EDIT2

好的 - 我应该更全面地阅读MSDN!这是AGGREGATE的语法:

  

聚合(Set_Expression [,Numeric_Expression])

遵循这个建议......

SELECT 
  [Measures].[Student Attendance] ON COLUMNS
FROM 
(
  SELECT 
      Filter
      (
        [Student].[Student].[Student].MEMBERS
       ,
          AGGREGATE(
            {[School Year].[School Year].&[2010] , [School Year].[School Year].&[2011]}
            ,[Measures].[Student Infractions]    
      )
    > 1 ON COLUMNS
  FROM [Education]
);

答案 1 :(得分:1)

您可以使用HAVING子句

With member hadInfraction 
as (
   iif(sum( {[School Year].[School Year].&[2010],[School Year].[School Year].&[2011]},
            [Measures].[Student Infractions]) > 1, 1,0)
)
   SELECT {[Measures].[Student Attendance] } ON 0,
     {[Student].[Student].[Student].Members}
Having [Measures].[hadInfraction] =1
On 1
From Education 

我几乎不使用FILTER功能 - 它很慢而且不灵活。 Having允许您根据所需的任何计算成员过滤任何集合。

编辑:只要你需要MDX生成,那么你应该考虑使用所有MDX浏览器的一般方法(Excel,SSMS等):

用户提供[学年]。[学年]。&amp; [2010],[学年]。[学年]。&amp; [2011]作为Cube切片,同时还需要测量滤镜。

  • 首先,为每个[School Year]生成子选择,仅选择 年:

    ... 来自(

    选择{[学年]。[学年]。&amp; [2010],[学年]。[学年]。&amp; [2011]} 0)

    来自[教育]

  • 第二,在顶层使用HAVING或FILTER来获得你需要的东西

问题是你应该自己构建额外的计算成员,一般使用AGGREGATE(通常你需要默认的聚合函数)。因此,您可能能够针对视觉编程查询拍摄100个可能场景中的1个。

但是,极少数情况下,MDX浏览器足够智能,可以使用维度过滤器和度量组成员过滤器生成查询。即使像SSMS / Excel这样的重型产品也会将此任务委托给纯MDX代码;

答案 2 :(得分:0)

那你为什么不在2010年和2011年的立方体中添加一个度量?添加它会显着降低复杂性。

最终查询可能如下所示:

WITH [Measures].[Student Attendance For Selected Years] AS
AGGREGATE(
                {
                  STRTOSET('[School Year].[School Year].&[2010]
                 ,[School Year].[School Year].&[2011]') ---STRTOSET function allows for this part to be a parameter
                },
                [Measures].[Student Infractions]
         )

SELECT [Measures].[Student Attendance] ON COLUMNS
 FROM [Education]
 WHERE FILTER([Student].[Student].children, [Measures].[Student Attendance For Selected Years]>1)

您需要做的是构建参数并将其传递到MDX的STRTOSET部分。请参阅here如何使用StrToSet函数与SSRS。你可以尝试类似的东西。

相关问题