如何模拟 SQL 从 mdx 中的两个不同查询中减去结果

How to mimic SQL subtraction of results from two different queries in mdx

我想做日期之间的趋势分析。对于实例当前日期 - 30 天 30-60 天,所以 on.Below 是可比较的 sql 查询的片段,但我想在 MDX 中做同样的事情。

SQL

SELECT
ROUND
(
    (
        (
            (
            SELECT
                SUM(del_pri_impr)
            FROM
                reporting.so_sli_calc_val a,
                reporting.user_group_tenant b,
                reporting.salesorder c
            WHERE
                created_on BETWEEN DATE(now()-30) AND DATE(now())
            )

            -

            (            
            SELECT
                SUM(del_pri_impr)
            FROM
                reporting.so_sli_calc_val a,
                reporting.user_group_tenant b,
                reporting.salesorder c
            WHERE
                created_on BETWEEN DATE(now()-60) AND DATE(now()-30)             
            )
        )

        /

        (
                   SELECT
                       SUM(del_pri_impr)
                   FROM
                       reporting.so_sli_calc_val a,
                       reporting.user_group_tenant b,
                     reporting.salesorder c
                 WHERE
                     created_on BETWEEN DATE(now()-60) AND DATE(now()-30)
        ) *100
    )

,
0
) AS trend

MDX:

WITH
 SET [~FILTER] AS
    {[Created_Date.Created_Hir].[Created_On].[2014-04-01]:[Created_Date.Created_Hir].[Created_On].[2014-04-30]}
  SET [~ROWS] AS
  {[Sales Order Attributes SO.Sales_order].[Sales Order ID].Members}
  SELECT
   NON EMPTY {[Measures].[CONT_AMT_GROSS], [Measures].[CONT_AMT_NET]} ON     COLUMNS,
   NON EMPTY [~ROWS] ON ROWS
   FROM [SALES_ORDER]
  WHERE [~FILTER]

到目前为止,我已经对日期进行了硬编码,这些日期将来自参数。 我在创建第二组以及如何在 MDX 中的两组之间进行减法时遇到困难。

您已经掌握了如何获取 "last 30 days from now" 和 "last 60 to last 30 days from now" 对应的日期集的逻辑。所以,我打算跳过那部分。

注意 - 在构建这些集合时您必须使用参数值。

这里要做的是先找到这几组日期对应的值,然后对它们进行运算。

您可以这样进行 -

WITH
  SET [~FILTER] AS
    {[Created_Date.Created_Hir].[Created_On].[2014-04-01]:[Created_Date.Created_Hir].[Created_On].[2014-04-30]}
  SET [~ROWS] AS
  {[Sales Order Attributes SO.Sales_order].[Sales Order ID].Members}
  SET [Last30Days] AS
  ... 
  SET [Last60ToLast30Days] AS
  ...
  MEMBER [~Last30Days - Now] AS
  Aggregate   
  (
      [Last30Days],
      [Measures].[SomeMeasure]
  )

  MEMBER [~Last60Days - Last30Days] AS
  Aggregate
  (
      [Last60ToLast30Days],
      [Measures].[SomeMeasure]
  )


  MEMBER [~Measure] AS
  ([~Last30Days - Now]-[~Last60Days - Last30Days] )/([~Last60Days - Last30Days] * 100), format_string = '#,##0'

  SELECT
   NON EMPTY {
                [Measures].[CONT_AMT_GROSS], 
                [Measures].[CONT_AMT_NET],
                [~Measure]
             } ON COLUMNS,
   NON EMPTY [~ROWS] ON ROWS
   FROM [SALES_ORDER]

Format_String 负责四舍五入。

不确定我是否完全同意 Sourav 的回答,因为我认为需要某种形式的聚合;创建包含集合的元组可能会引发异常。

这是一个针对 AdvWrks 的简单模型,它已经过测试并会为您做减法:

WITH 
  SET [Set1] AS 
      [Date].[Calendar].[Date].&[20060301]
    : 
      [Date].[Calendar].[Date].&[20070308] 
  SET [Set2] AS 
      [Date].[Calendar].[Date].&[20070308]
    : 
      [Date].[Calendar].[Date].&[20080315]
  MEMBER [Date].[Calendar].[All].[Set1Agg] AS 
     aggregate([Set1])
  MEMBER [Date].[Calendar].[All].[Set2Agg] AS 
     aggregate([Set2])

  MEMBER [Date].[Calendar].[All].[x] AS 
    (
      [Date].[Calendar].[All].[Set1Agg]
     ,[Measures].[Internet Sales Amount]
    ) 
  MEMBER [Date].[Calendar].[All].[y] AS 
    (
      [Date].[Calendar].[All].[Set2Agg]
     ,[Measures].[Internet Sales Amount]
    ) 
  MEMBER [Date].[Calendar].[All].[x-y] AS 
    [Date].[Calendar].[All].[x] - [Date].[Calendar].[All].[y] 
SELECT 
  {
    [Date].[Calendar].[All].[x]
   ,[Date].[Calendar].[All].[y]
   ,[Date].[Calendar].[All].[x-y]
  } ON 0
 ,[Product].[Category].[Category] ON 1
FROM [Adventure Works];

反思您的代码可能如下所示:

WITH 
  SET [Set1] AS 
      [Created_Date.Created_Hir].[Created_On].[2014-04-01]
    : 
      [Created_Date.Created_Hir].[Created_On].[2014-04-30] 
  SET [Set2] AS 
      [Created_Date.Created_Hir].[Created_On].[2014-03-01]
    : 
      [Created_Date.Created_Hir].[Created_On].[2014-03-31] 
  MEMBER [Created_Date.Created_Hir].[All].[Set1Agg] AS 
    Aggregate([Set1]) 
  MEMBER [Created_Date.Created_Hir].[All].[Set2Agg] AS 
    Aggregate([Set2]) 
  MEMBER [Measures].[~Last30Days - Now] AS 
    (
      [Created_Date.Created_Hir].[All].[Set1Agg]
     ,[Measures].[SomeMeasure]
    ) 
  MEMBER [Measures].[~Last60Days - Last30Days] AS 
    (
      [Created_Date.Created_Hir].[All].[Set2Agg]
     ,[Measures].[SomeMeasure]
    ) 
  MEMBER [Measures].[~Measure] AS 

        ([Measures].[~Last30Days - Now] - [Measures].[~Last60Days - Last30Days])
      / 
        [Measures].[~Last60Days - Last30Days]
    * 100 
   ,format_string = '#,##0' 
  SET [~ROWS] AS 
    {
      [Sales Order Attributes SO.Sales_order].[Sales Order ID].MEMBERS
    } 
SELECT 
  NON EMPTY 
    {
      [Measures].[CONT_AMT_GROSS]
     ,[Measures].[CONT_AMT_NET]
     ,[Measures].[~Measure]
    } ON COLUMNS
 ,NON EMPTY 
    [~ROWS] ON ROWS
FROM [SALES_ORDER]
WHERE 
  [~FILTER];