用于计算普通成员的 MDX - EXISTS 替代方案

MDX to count common members - EXISTS alternative

让我用[Adventure Works]立方体的例子来描述这个问题。

以下 MDX returns 计数为 17473

SELECT NON EMPTY { [Measures].[Internet Order Count] } ON COLUMNS,

[Internet Sales Order Details].[Sales Order Number] on ROWS

FROM [Adventure Works])

WHERE ( [Sales Reason].[Sales Reason].&[1] -- price

和以下 returns 计数 3515

SELECT NON EMPTY { [Measures].[Internet Order Count] } ON COLUMNS ,

[Internet Sales Order Details].[Sales Order Number] on ROWS

FROM [Adventure Works]

WHERE ( [Sales Reason].[Sales Reason].&[2]) -- on promotion

我想统计[Sales Reason].&1和[Sales Reason].&[2]

中常见的[Sales Order Number]

SQL 等价于:

select count(distinct f.SalesOrderNumber)
from FactInternetSales f
join FactInternetSalesReason fs 
on f.SalesOrderNumber = fs.SalesOrderNumber and f.SalesOrderLineNumber = fs.SalesOrderLineNumber
where fs.SalesReasonKey = 1 and fs.SalesOrderNumber in
      (select SalesOrderNumber from FactInternetSalesReason fs1 where fs1.SalesReasonKey = 2)

-- sales reason 1 = 17473
-- sales reason 2 = 3515
-- common 1689

我使用以下 mdx 得到了共同计数:

WITH MEMBER [Measures].[common] AS count

   (  exists ( exists ([Internet Sales Order Details].[Sales Order Number].[Sales Order Number].Members,
         [Sales Reason].[Sales Reason].&[1],"Internet Orders" 
         ),
         [Sales Reason].[Sales Reason].&[2],"Internet Orders" 
        )
    )

SELECT NON EMPTY [Measures].[common] ON COLUMNS

FROM [Adventure Works] 

-- 1689

但是使用 EXISTS 对我的要求来说相当慢。请提出替代方案。

另请参阅相关主题here

谢谢

请尝试将这两个原因作为一个集合添加到 WHERE 子句中:

SELECT 
  NON EMPTY 
    {[Measures].[Internet Order Count]} ON COLUMNS
 ,[Internet Sales Order Details].[Sales Order Number] ON ROWS
FROM [Adventure Works]
WHERE 
  {
    [Sales Reason].[Sales Reason].&[2]
   ,[Sales Reason].[Sales Reason].&[1]
  };

这里有一个运行速度比较快的替代方案,只看常用命令,不使用EXISTS函数:

WITH 
  SET [AllOrders] AS 
    [Internet Sales Order Details].[Sales Order Number].[Sales Order Number].MEMBERS 
  SET [OrdersIntersection] AS 
    Intersect
    (
      NonEmpty
      (
        [AllOrders]
       ,{
          (
            [Sales Reason].[Sales Reason].&[1]
           ,[Measures].[Internet Order Count]
          )
        }
      )
     ,NonEmpty
      (
        [AllOrders]
       ,{
          (
            [Sales Reason].[Sales Reason].&[2]
           ,[Measures].[Internet Order Count]
          )
        }
      )
    ) 
  MEMBER [Measures].[commonCount] AS 
    [OrdersIntersection].Count 
SELECT 
  //NON EMPTY //<<not needed
    [Measures].[commonCount] ON COLUMNS
FROM [Adventure Works];