mdx非空排除存在的值

时间:2015-02-05 21:23:15

标签: mdx

我对Nonempty()函数的理解是它采用第一个集合表达式,将其应用于第二集表达式并删除第二个表达式中没有值的表达式。

我有

WITH
SET [Date Range] AS
    Filter(
        [Date].[Date].[Date],
        [Date].[Date].CurrentMember.Member_Value >= CDate(@StartDateParam) AND
        [Date].[Date].CurrentMember.Member_Value <= CDate(@EndDateParam)
    )

MEMBER [Measures].[DateValue] AS
    [Date].[Date].CurrentMember.Member_Value

SELECT
{
    [Measures].[DateValue],
    [Measures].[Work Item Count]
} ON COLUMNS,
{
    CrossJoin(
        [Date Range],
        --NonEmpty(
            [Work Item].[System_State].[System_State]
        --  ,[Measures].[Work Item Count]
        --)
    )
} ON ROWS
FROM [Team System]

返回

Date     | State    | DateValue  | WorkItemCount
2/1/2015 | Active   | 2/1/2015.. | 2
2/1/2015 | Resolved | 2/1/2015.. | (null)
2/2/2015 | Active   | 2/2/2015.. | 1
2/2/2015 | Resolved | 2/2/2015.. | 1
2/3/2015 | Active   | 2/3/2015.. | 0
2/3/2015 | Resolved | 2/3/2015.. | 2

当我取消注释上述非空代码时, 我明白了:

Date     | State    | DateValue  | WorkItemCount
2/1/2015 | Resolved | 2/1/2015.. | (null)
2/2/2015 | Resolved | 2/2/2015.. | 1
2/3/2015 | Resolved | 2/3/2015.. | 2

我期待得到:

Date     | State    | DateValue  | WorkItemCount
2/1/2015 | Active   | 2/1/2015.. | 2
2/2/2015 | Active   | 2/2/2015.. | 1
2/2/2015 | Resolved | 2/2/2015.. | 1
2/3/2015 | Resolved | 2/3/2015.. | 2

这里发生了什么?

这在SQL Server 2014上发生,因此SSAS MDX NonEmpty issue中的答案不适用

2 个答案:

答案 0 :(得分:0)

NonEmpty()仅删除提供null*null的交叉连接结果。当您遇到Resolved*null这样的情况时,NonEmpty不起作用。此外,这种方法不会给你最好的表现。试试这个:

WITH
SET [Date Range] AS
Filter(
    [Date].[Date].[Date],
    [Date].[Date].CurrentMember.Member_Value >= CDate(@StartDateParam) AND
    [Date].[Date].CurrentMember.Member_Value <= CDate(@EndDateParam)
)

MEMBER [Measures].[DateValue] AS
[Date].[Date].CurrentMember.Member_Value

// add member to filter out null
// Work Item Count condition 
member hasState as ( iif( ISEMPTY([Measures].[Work Item Count]), 0, 1) )

SELECT
{
   [Measures].[DateValue],
   [Measures].[Work Item Count]
} ON COLUMNS,
{

       [Date Range] *
           [Work Item].[System_State].[System_State].members
 } 
 having [Measures].[hasState] = 1
 ON ROWS
 FROM [Team System]

答案 1 :(得分:0)

尽量保持简单 只需稍稍移动nonEmpty

WITH
SET [Date Range] AS
    Filter(
        [Date].[Date].[Date],
        [Date].[Date].CurrentMember.Member_Value >= CDate(@StartDateParam) AND
        [Date].[Date].CurrentMember.Member_Value <= CDate(@EndDateParam)
    )

MEMBER [Measures].[DateValue] AS
    [Date].[Date].CurrentMember.Member_Value

SELECT
{
    [Measures].[DateValue],
    [Measures].[Work Item Count]
} ON COLUMNS,
{
    NonEmpty(
       [Date Range]
       * [Work Item].[System_State].[System_State]
      ,[Measures].[Work Item Count]
      )
} ON ROWS
FROM [Team System]

修改

@George发布了一个有趣的方法。他使用了帮助程序,然后输入HAVING子句。这个子句很快,应尽可能使用,但我认为创建新度量的开销会抵消HAVING的性能提升。因此,可以保持简单并使用NonEmpty ..

我在2006年使用Chris Webb撰写的这篇文章中类似于脚本的简单示例进行了测试:https://cwebbbi.wordpress.com/2006/01/04/the-having-clause/

--takes 17 secs
WITH 
  MEMBER [Measures].[hasQuant] AS 
    IIF
    (
      IsEmpty([Measures].[Internet Order Quantity])
     ,0
     ,1
    ) 
SELECT 
  [Measures].[Internet Order Quantity] ON 0
 ,{
      [Date].[Date].MEMBERS*
      [Product].[Subcategory].MEMBERS*
      [Geography].[Country].MEMBERS*
      [Customer].[Gender].MEMBERS
  } HAVING 
  [Measures].[hasQuant] = 1 ON 1
FROM [Adventure Works];

而只是简单地使用NonEmpty

-- secs 11 secs
SELECT 
  [Measures].[Internet Order Quantity] ON 0
 ,NonEmpty
  (
      [Date].[Date].MEMBERS*
      [Product].[Subcategory].MEMBERS*
      [Geography].[Country].MEMBERS*
      [Customer].[Gender].MEMBERS
   ,[Measures].[Internet Order Quantity]
  ) ON 1
FROM [Adventure Works];