2015-11-02 59 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

相關問題