MDX深入查询生成

MDX深入查询生成,mdx,olap,activepivot,Mdx,Olap,Activepivot,我正在编写一些与ActivePivot集成的客户端代码。作为其中的一部分,我需要能够处理深入请求,并在将其提交到服务器之前生成经过适当修改的MDX查询 下面是一个使用ActivePivot沙盒多维数据集的简单示例。假设基本查询为: SELECT { Hierarchize ( { [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember], [Bookings].[DEFAULT

我正在编写一些与ActivePivot集成的客户端代码。作为其中的一部分,我需要能够处理深入请求,并在将其提交到服务器之前生成经过适当修改的MDX查询

下面是一个使用ActivePivot沙盒多维数据集的简单示例。假设基本查询为:

SELECT
{
    Hierarchize
    (
        {
            [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember],
            [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children
        }
    )
} ON COLUMNS,
{
    Hierarchize
    (
        {
            [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember],
            [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children
        }
    )
} ON ROWS
FROM [EquityDerivativesCube]
当用户深入了解2M期限时,我需要生成:

SELECT
{
    Hierarchize
    (
        {
            [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember],
            [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children
        }
    )
} ON COLUMNS,
{
    Hierarchize
    (
        {
            [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember],
            [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children,
            [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M].Children
        }
    )
} ON ROWS
FROM [EquityDerivativesCube]
现在,对于像上面这样的简单查询,我可以在一个基本查询中定义一个替换点,并向其中注入深入的路径。例如,上面的基本查询是:

SELECT
{
    Hierarchize
    (
        {
            {0}
        }
    )
} ON COLUMNS,
{
    Hierarchize
    (
        {1}
    )
}
ON ROWS FROM [EquityDerivativesCube]
显然,取代点需要他们的花括号逃逸,但你明白了

但对于更复杂的查询,例如在一个轴上有多个成员的查询,这种方法很快就会崩溃。例如,下面是一个列维度上有两个成员的查询:

SELECT
Hierarchize(
    Union(
        CrossJoin(
            {[Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember]},
             {[Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember]}
        ),
         Union(
            CrossJoin(
                {[Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember]},
                 [Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children
            ),
             Union(
                CrossJoin(
                    [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children,
                     {[Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember]}
                ),
                 CrossJoin(
                    [Bookings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children,
                     [Underlyings].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children
                )
            )
        )
    )) 
ON COLUMNS,
{Hierarchize(
    {[TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember],
     [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children})} 
ON ROWS
FROM [EquityDerivativesCube]
我需要能够检测针对任何可钻取成员的钻取请求,并在重新提交之前相应地修改查询

所以我想知道的是怎么做?我最初的希望是MDX本身定义了一些标准机制,根据您传递的一些参数提供深入查询。然而,我还没有找到像这样的东西

因此,我担心我唯一的办法就是自己解析查询,并将深入信息动态注入AST,然后生成新查询。有人能证实这一点,或者提供一种替代方法吗?

您可以使用带有递归标志的函数

例如:

DrilldownMember({ [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember]}, { [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember], [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M]}, RECURSIVE)
它将返回与相同的成员

{
    {[TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember]},
    [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children,
    [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M].Children
}
您可以使用带有递归标志的函数

例如:

DrilldownMember({ [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember]}, { [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember], [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M]}, RECURSIVE)
它将返回与相同的成员

{
    {[TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember]},
    [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].Children,
    [TimeBucket].[DEFAULT_HIERARCHY].[ALL].[AllMember].[2M].Children
}

谢谢-我知道这对简单的查询有什么帮助,但我不知道它如何应用于更复杂的查询。我更新了我的问题,加入了一个例子。你能看一看并评论/更新你的答案吗?在做了更多的实验之后,我想我需要做的是使用CrossJoin而不是Union——这是由我使用的工具生成的,该工具为维度的每个成员调用了一个DrilldownMember。因此,我将维护一组成员,以便对每个维度成员进行深入研究。当用户深入到成员中时,我将添加到适当的集合并相应地生成查询。当他们钻取时,我会从适当的集合中移除。我很想听听你对这种方法的看法。谢谢-我知道这对简单的查询有什么帮助,但我不知道它如何应用于更复杂的查询。我更新了我的问题,加入了一个例子。你能看一看并评论/更新你的答案吗?在做了更多的实验之后,我想我需要做的是使用CrossJoin而不是Union——这是由我使用的工具生成的,该工具为维度的每个成员调用了一个DrilldownMember。因此,我将维护一组成员,以便对每个维度成员进行深入研究。当用户深入到成员中时,我将添加到适当的集合并相应地生成查询。当他们钻取时,我会从适当的集合中移除。我很想听听你对这种方法的看法。