以编程方式生成 MDX 行计数查询的最简单方法?

Posted

技术标签:

【中文标题】以编程方式生成 MDX 行计数查询的最简单方法?【英文标题】:Easiest way to programmatically generate MDX rowcount query? 【发布时间】:2015-02-02 16:21:39 【问题描述】:

现在我正在处理一个可以生成和返回 SQL 或 MDX 查询的程序(取决于查询的源数据库)。我正在努力添加一个功能来计算给定查询返回的所有行。

现在,我对 SQL 有了一些了解,所以我能够解析表名并生成行数。但是,MDX 对我来说是一个全新的野兽。

在 SQL 中,我正在创建:

SELECT 
   COUNT(SUM)
AS ROWS
FROM
(
  COUNT(*) AS COUNT FROM TABLE1
  UNION ALL
  COUNT(*) AS COUNT FROM TABLE2
  UNION ALL
  COUNT(*) AS COUNT FROM TABLE3
  ETC...
)

现在,我想知道的是,我将如何使用 MDX 做类似的事情?我在 MDX 上做了一些阅读,从我收集到的基本符号是

[Dimension].[Hierarchy].[Level]

现在使用 SQL,我从生成的较大查询中解析出表名,然后简单地将它们插入到以编程方式生成的新查询中。我必须从更大的 MDX 查询中获取什么来生成我自己的行计数查询并将其发送运行?我正在处理的 MDX 的一个更简单的例子是:

 WITH
     MEMBER [BUSINESS1].[XQE_RS_CM1] AS '([BUSINESS1].[COMPANY_H].[all])', SOLVE_ORDER = 8
     MEMBER [BUSINESS2].[XQE_RS_CM0] AS '([BUSINESS2].[all])', SOLVE_ORDER = 4
SELECT 
     NON EMPTY [BUSINESS2].[ALL_TIME_H].[CALENDAR_YEAR_L].MEMBERS AS [XQE_SA1] , HEAD([BUSINESS2].[XQE_RS_CM0], COUNT(HEAD([XQE_SA1]), INCLUDEEMPTY)) DIMENSION PROPERTIES PARENT_LEVEL,  PARENT_UNIQUE_NAME ON AXIS(0), 
     NON EMPTY [BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS AS [XQE_SA0] , HEAD([BUSINESS1].[XQE_RS_CM1], COUNT(HEAD([XQE_SA0]), INCLUDEEMPTY)) DIMENSION PROPERTIES PARENT_LEVEL,  PARENT_UNIQUE_NAME ON AXIS(1), 
     NON EMPTY [Measures].[Measures].[BUSINESS3] DIMENSION PROPERTIES PARENT_LEVEL,  PARENT_UNIQUE_NAME ON AXIS(2)
FROM 
    [SOURCE]  CELL PROPERTIES CELL_ORDINAL,  FORMAT_STRING,  VALUE

任何见解都会很棒,谢谢。

【问题讨论】:

哇 - 3 轴是非常罕见的!使用这些数据的工具是什么? 商业智能应用程序。我正在开发一个内部使用工具来帮助分析一些正在运行的查询。 我以前使用 Proclarity - 现在使用 Pyramid。也可以使用 s-s-rS 和 Excel 来消费mdx。我从未见过使用 AXIS(2) 的外部查询。我在子选择中看到过这一点,但从未在主查询中看到过。一旦使用了这个额外的轴,你并没有真正得到一个平面表,所以“计算行数”有点用词不当。 我想您需要计算每个轴的成员并将这些数字相乘? 这可能行得通。您实际上是在建议我对每个成员使用 .count,然后将结果相乘,对吗?我知道我不是在处理一张平板,这是我困惑的部分原因。由于您是唯一回复的人,您想将您的 cmets 格式化为答案,我会给您一张支票? 【参考方案1】:

乍一看,您的脚本看起来很合理,但拆开后它变得有点(!)更复杂。

此脚本与其他脚本的主要区别在于它使用了axis(2)。在子选择中,经常使用额外的维度,但这有点奇怪,因为大多数客户无法处理 3 维单元集 - 所以我对消耗这些信息的内容很感兴趣?

另外,[BUSINESS1].[XQE_RS_CM1] 成员和[BUSINESS2].[XQE_RS_CM0] 一样是单个成员,那么HEAD... 部分的意义何在?

WITH
     MEMBER [BUSINESS1].[XQE_RS_CM1] AS 
         ([BUSINESS1].[COMPANY_H].[all]), SOLVE_ORDER = 8
     MEMBER [BUSINESS2].[XQE_RS_CM0] AS 
         ([BUSINESS2].[all]), SOLVE_ORDER = 4
SELECT 
     NON EMPTY 
         [BUSINESS2].[ALL_TIME_H].[CALENDAR_YEAR_L].MEMBERS AS [XQE_SA1] 
         ,HEAD(
            [BUSINESS2].[XQE_RS_CM0], 
            COUNT(
              HEAD([XQE_SA1])
             ,INCLUDEEMPTY
            )
          )
     ON AXIS(0), 
     NON EMPTY 
         [BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS AS [XQE_SA0] 
         ,HEAD(
            [BUSINESS1].[XQE_RS_CM1], 
            COUNT(
              HEAD([XQE_SA0])
             ,INCLUDEEMPTY
            )
          )
     ON AXIS(1), 
     NON EMPTY 
        
          [Measures].[Measures].[BUSINESS3]
         
     ON AXIS(2)
FROM 
    [SOURCE]

以下是否返回与原始脚本相同的数据?

SELECT 
     NON EMPTY 
         
          [BUSINESS2].[ALL_TIME_H].[CALENDAR_YEAR_L].MEMBERS 
         ,[BUSINESS2].[all]
         
     ON 0, 
     NON EMPTY 
         
          [BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS
         ,[BUSINESS1].[COMPANY_H].[all]
         
     ON 1
FROM  [SOURCE]
WHERE [Measures].[Measures].[BUSINESS3];

然后,您需要计算的是在以下行中返回的成员数:


  [BUSINESS1].[COMPANY_H].[COMPANY_CD__L].MEMBERS
 ,[BUSINESS1].[COMPANY_H].[all]

【讨论】:

太好了,清楚了很多。感谢您抽出宝贵的时间。至于你关于 HEAD 的问题,MDX 是从一个简单的表达式生成的,所以它并不总是完全合乎逻辑的。

以上是关于以编程方式生成 MDX 行计数查询的最简单方法?的主要内容,如果未能解决你的问题,请参考以下文章

MDX 计算的测量计数

MDX 向下钻取查询生成

使用计算成员传递参数 - MDX

以编程方式查找最新 Qt 版本号的最简单方法是啥?

在 Scrapy >= 0.14 中以编程方式启动爬虫的最简单方法是啥

存储大型 SQL 数据的查询和计数的最有效方式