2015-11-02 53 views
0

层次结构也能正常工作:前X与RestOf成员,其中X和Y是从不同的维度

WITH 
    SET [AllCountries] AS [Country].[Country].MEMBERS 
    SET [AllStates] AS [State-Province].[State-Province].MEMBERS 
    SET [Top2States] AS 
    Generate 
    (
     [AllCountries] 
    ,TopCount 
     (
     (EXISTING 
      [AllStates]) 
     ,3 
     ,[Measures].[Internet Order Count] 
    ) 
    ) 
    MEMBER [State-Province].[All].[RestOfCountry] AS 
    Aggregate({(EXISTING {[AllStates]} - [Top2States])}) 
SELECT 
    {[Measures].[Internet Order Count]} ON COLUMNS 
,{ 
     [AllCountries] 
    * 
     { 
     [State-Province].[All] 
     ,[Top2States] 
     ,[State-Province].[All].[RestOfCountry] 
     } 
    } ON ROWS 
FROM [Adventure Works]; 

EXISTING关键字有很大帮助。

如果两个层次ON ROWS是不是来自同一个维度,在国家和状态都在上面的方法,那么我们有类似如下:

WITH 
    SET [AllCountries] AS [Country].[Country].MEMBERS 
    SET [AllCats]  AS [Product].[Category].[Category].MEMBERS 
    SET [Top5Cats] AS 
    Generate 
    (
     [AllCountries] 
    ,TopCount 
     (
     (EXISTING 
      [AllCats]) 
     ,5 
     ,[Measures].[Internet Order Count] 
    ) 
    ) 
    MEMBER [Product].[Category].[All].[RestOfProds] AS 
    Aggregate({(EXISTING {[AllCats]} - [Top5Cats])}) 
SELECT 
    {[Measures].[Internet Order Count]} ON COLUMNS 
,{ 
     [AllCountries] 
    * 
     { 
     [Product].[Category].[All] 
     ,[Top5Cats] 
     ,[Product].[Category].[All].[RestOfCountry] 

     } 
    } ON ROWS 
FROM [Adventure Works]; 

您可以在结果中看到上面说的是,按照相同的顺序针对每个国家重复相同的一组类别,即,引擎没有找到每个国家的topCount。 现在是多余的。

我们如何调整上面的第二个脚本,使其具有与顶级脚本类似的功能?


编辑

一个更好的例子是以下使用的产品。就好像引擎找到所有国家的TopCount,然后对每个国家设置相同的设置。我想了TopCount每个国家:

WITH 
    SET [AllCountries] AS 
    [Country].[Country].MEMBERS 
    SET [AllProds] AS 
    [Product].[Product].[Product].MEMBERS 
    SET [Top5Prods] AS 
    Generate 
    (
     [AllCountries] 
    ,TopCount 
     (
     (EXISTING 
      [AllProds]) 
     ,5 
     ,[Measures].[Internet Order Count] 
    ) 
    ) 
    MEMBER [Product].[Product].[All].[RestOfProds] AS 
    Aggregate({(EXISTING {[AllProds]} - [Top5Prods])}) 
SELECT 
    {[Measures].[Internet Order Count]} ON COLUMNS 
,NON EMPTY 
    { 
     [AllCountries] 
     * 
     { 
      [Product].[Product].[All] 
     ,[Top5Prods] 
     ,[Product].[Product].[All].[RestOfProds] 
     } 
    } ON ROWS 
FROM [Adventure Works]; 

EDIT2

这是通过Sourav的思想的最新版本 - 不幸的是,RestOfProds成员不正常:

WITH 
    SET [AllCountries] AS 
    [Country].[Country].MEMBERS 
    SET [AllProds] AS 
    [Product].[Product].[Product].MEMBERS 
    SET [Top5Prods] AS 
    Generate 
    (
     [AllCountries] AS a 
    , 
     { 
      (
       a.Current 
      ,[Product].[Product].[All] 
      ) 
      + 
      //The top x prods 
      TopCount 
      (
       NonEmpty 
       (
       a.Current * [AllProds] 
       ,[Measures].[Internet Sales Amount] 
      ) 
      ,5 
      ,[Measures].[Internet Sales Amount] 
      ) 
     } 
    ) 
    SET [RestOfProds] AS 
    Extract 
    (
     {[AllCountries] * [AllProds]} - [Top5Prods] 
    ,[Product].[Product] 
    ) 
    MEMBER [Product].[Product].[All].[RestOfProds] AS 
    Aggregate([RestOfProds]) 
SELECT 
    {[Measures].[Internet Sales Amount]} ON COLUMNS 
,{ 
    [Top5Prods] 
    , 
    [AllCountries] * [Product].[Product].[All].[RestOfProds] 
    } ON ROWS 
FROM [Adventure Works]; 

EDIT3

以下具有正确的顺序,以使构件RestOfProds总是跟随它的相应的顶5

WITH 
    SET [AllCountries] AS 
    [Country].[Country].MEMBERS 
    SET [AllProds] AS 
    [Product].[Product].[Product].MEMBERS 
    SET [Top5Prods] AS 
    Generate 
    (
     [AllCountries] AS a 
    ,{ 
     //The top x prods 
     TopCount 
     (
      NonEmpty 
      (
      a.Current * [AllProds] 
      ,[Measures].[Internet Sales Amount] 
     ) 
     ,5 
     ,[Measures].[Internet Sales Amount] 
     ) 
     } 
    ) 
    MEMBER [Product].[Product].[All].[RestOfProds] AS 
    Aggregate([Country].CurrentMember * [AllProds] - [Top5Prods]) 
SELECT 
    {[Measures].[Internet Sales Amount]} ON COLUMNS 
,Generate 
    (
    [AllCountries] AS X 
    , 
     Order 
     (
     Intersect 
     (
      X.CurrentMember * [AllProds] 
     ,[Top5Prods] 
     ) 
     ,[Measures].[Internet Sales Amount] 
     ,bdesc 
    ) 
    + 
     {X.CurrentMember * {[Product].[Product].[All].[RestOfProds]}} 
) ON ROWS 
FROM [Adventure Works]; 

Edit4

以下具有正确的顺序,使会员RestOfProds总是遵循它的各自的前5+我已经在行上添加了另一组:

WITH 
    SET [2months] AS 
    { 
     [Date].[Calendar].[Month].&[2007]&[9] 
    ,[Date].[Calendar].[Month].&[2007]&[10] 
    } 
    SET [AllCountries] AS 
    [Country].[Country].MEMBERS 
    SET [MthsCountries] AS 
    [2months] * [AllCountries] 
    SET [AllProds] AS 
    [Product].[Product].[Product].MEMBERS 
    SET [Top5Prods] AS 
    Generate 
    (
     [MthsCountries] AS A 
    ,{ 
     //The top x prods 
     TopCount 
     (
      NonEmpty 
      (
      A.Current * [AllProds] 
      ,[Measures].[Internet Sales Amount] 
     ) 
     ,5 
     ,[Measures].[Internet Sales Amount] 
     ) 
     } 
    ) 
    MEMBER [Product].[Product].[All].[RestOfProds] AS 
    Aggregate 
    (
     ([Date].[Calendar].CurrentMember,[Country].CurrentMember) * [AllProds] 
     - 
     [Top5Prods] 
    ) 
SELECT 
    {[Measures].[Internet Sales Amount]} ON COLUMNS 
,Generate 
    (
    [MthsCountries] AS X 
    , 
     Order 
     (
     Intersect 
     (
      X.Current * [AllProds] 
     ,[Top5Prods] 
     ) 
     ,[Measures].[Internet Sales Amount] 
     ,bdesc 
    ) 
    + 
     {X.Current * {[Product].[Product].[All].[RestOfProds]}} 
) ON ROWS 
FROM [Adventure Works]; 

回答

2

EXISTING当在命名集上使用时,并没有真正有所作为,因为命名集是在轴成员布局之前创建的。在你的情况下,GENERATE实际上只是创建静态集合,然后在轴上所有东西都只是交叉连接。

要使TopCount脚本正常工作,您需要处理一个集合内的所有cross joins,以便一起评估所有内容。我不知道,不过你可以试试下面的:

WITH 
    SET [AllCountries] AS [Country].[Country].MEMBERS 
    SET [AllCats] AS [Product].[Category].[Category].MEMBERS 
    SET [Top5Cats] AS 
    Generate 
    (
     [AllCountries] as a 
    , 
    { 
    (a.current , [Product].[Category].[All]) //The ALL member 
    + 
    TopCount //The top 2 categories 
     (
     NonEmpty((a.current * [AllCats]) , (a.CURRENT, [Measures].[Internet Order Count])) 
     ,2 
     ,[Measures].[Internet Order Count]  
    ) 
     } 
    + 
    { //The rest of the members 
    a.current * [AllCats] 
    - 
    a.current *{  
    TopCount 
     (
     NonEmpty([AllCats] , (a.CURRENT, [Measures].[Internet Order Count])) 
     ,2 
     ,[Measures].[Internet Order Count]  
    ) 
     } 
     } 
    ) 

    MEMBER [Product].[Category].[All].[RestOfProds] AS 
    Aggregate({(EXISTING {[AllCats]} - [Top5Cats])}) 

SELECT 
    {[Measures].[Internet Order Count]} ON COLUMNS, 
[Top5Cats] ON ROWS 
FROM [Adventure Works]; 

编辑: 如果您需要RestOfCats成员,您可以添加该代码。

SET [RestOfCats] AS 
EXTRACT 
    (
    { 
    [AllCountries] * [AllCats] 
    - 
    [Top5Cats] 
    }, 
    [Product].[Category] 
    ) 

MEMBER [Product].[Category].[All].[RestOfCats] AS 
Aggregate([RestOfCats]) 

EDIT 2

继续在你的榜样,在定义还去掉 '全部' 成员。

SET [RestOfProds] AS 
    Extract 
    (
     {[AllCountries] * [AllProds]} - [Top5Prods] - [AllCountries]*[Product].[Product].[All] 
    ,[Product].[Product] 
    ) 
+0

(提高)虽然这仍然不工作'RestOfProds' – whytheq

+0

我不dont看到upvote! – SouravA

+0

你的意思是说,'{ a.current * [AllCats] - a.current * { TopCount上 ( 非空([AllCats],(a.CURRENT,[措施] [网上订购计数] )) ,2 ,[Measures]。[Internet Order Count] ) }'部分是无效的? – SouravA

1

如果您在同一维中交叉连接多个层次结构,则只会显示有效组合。这称为自动存在,它解释了为什么第一个查询可以像你想要的那样工作。

当从不同维度交叉连接层次结构时,自动存在不会发生。我认为这解释了第二个查询中返回的奇怪组合。

尝试在ON ROWS定义的开头添加NON EMPTY。那么它只会返回具有互联网订单计数度量值的组合(无论哪种度量都在列上)。这是限制交叉连接的正确方法。

如果你不想在互联网上订购数量不是空的,那么你需要一个NonEmpty(,[Measures]。[另一个度量])不同的度量?

编辑:看起来问题与自动存在无关,但与每个国家执行不同的TopCount有关。所以这个信息可能会帮助别人,但不是这个问题的答案。

+0

感谢您的帮助。添加'NON EMPTY'可以消除空白行,但让我将Category更改为Product,并且您可以看到针对每个国家/地区重复使用同一组产品:我认为它为所有'国家/地区查找'TopCount',然后对每个国家使用它。 – whytheq

+1

看起来我在这种情况下过分简化了问题,并且SouravA正在与TopCount相关的解决方案上。 – GregGalloway

+0

感谢格雷格 - 我正在测试Sourav的想法 – whytheq

1

这似乎是确定的工作:虽然遗憾的是它并没有这么简单

WITH 
    SET [AllCountries] AS 
    [Country].[Country].MEMBERS 
    SET [AllProds] AS 
    [Product].[Product].[Product].MEMBERS 
    SET [Top5Prods] AS 
    Generate 
    (
     [AllCountries] AS a 
    ,{ 
      (
      a.CurrentMember 
      ,[Product].[Product].[All] 
     ) 
     + 
      //The top x prods 
      a.CurrentMember 
      * 
      TopCount 
      (
       [AllProds] 
      ,5 
      ,[Measures].[Internet Sales Amount] 
      ) 
     } 
    ) 
    MEMBER [Product].[Product].[All].[Other Products] AS 
    Aggregate 
    (
     [Country].CurrentMember * [Product].[Product].[Product].MEMBERS 
     - 
     [Top5Prods] 
    ) 
SELECT 
    {[Measures].[Internet Sales Amount]} ON COLUMNS 
,Hierarchize(
    { 
    [Top5Prods] 
    ,[AllCountries] * [Product].[Product].[All].[Other Products] 
    } 
) ON ROWS 
FROM [Adventure Works]; 
+0

我准备好了答案,但看起来你明白了。是的,我认为你需要使用'currentmember'函数来获取“RestOf”成员。 +1你的 – SouravA

+0

@SouravA只是试图按照正确的顺序排列ROWS! ..先由All成员分区,然后是Top5,然后是其他产品成员。就目前而言,它是将所有其他产品夹在网格结尾。 – whytheq

相关问题